1

So my server (running Drupal 7) is getting this information:

[field_picture] => Array
    (
        [und] => Array
            (
                [0] => Array
                    (
                        [file] => iVBORw0KGgoAAAANSUhEUgAAAIwAAACMCAYAAA..... (the rest of a huge base64 string)
                        [filename] => test.png
                        [filemime] => image/png
                        [target_uri] => test.png
                        [filepath] => public://
                        [mimeType] => image/png
                    )

            )

    )

This is to a user endpoint, and this is the only field that doesn't update.

The rest of what is sent to the server looks like this:

[field_description] => Array
        (
            [und] => Array
                (
                    [0] => Array
                        (
                            [value] => 
                            [format] => 
                            [safe_value] => 
                        )

                )

        )

[uid] => 22
[roles] => Array
    (
        [2] => authenticated user
    )

And my AJAX to put this up:

    $.ajax({
        url: SITE_URL + "/" + ENDPOINT + "/user/" + localStorage.uid,
        type: 'PUT',
        crossDomain: true,
        headers: {
            'X-CSRF-Token': token
        },
        contentType: 'application/json',
        data: JSON.stringify(json),

...etc

The request doesn't fail (or at least it doesn't go to my error callback) - what is going on here and why isn't it saving?

1
  • Watchdog errors? File system permissions?
    – Felix Eve
    Commented Oct 20, 2017 at 0:05

1 Answer 1

0

You need to make two requests, the first you will POST the base64 encoded string of the file which in turn will return to you the file id, at which point you can make the second call to save the user entity with the file id on the field in question. I have a blog post about this here: http://tylerfrankenstein.com/code/drupal-services-file-create-example-json-and-jquery

Here's the gist of it (assuming your endpoint path is api):

// Get the file id...
$.ajax({
  type: "post",
  data: {
    "file":{
      "file": my_base_64_encoded_image_string,
      "filename": "my_image.jpg",
      "filepath": "public://my_image.jpg",
    }
  },
  url: 'https://www.example.com/api/file.json',
  dataType: 'json',
  success: function(result) {

    // Now that we have the file id, save it on the user entity.
    var userAccount = {
      field_picture: { und: [ { fid: result.fid } ] }
    };

    $.ajax({
      url: "https://www.example.com/api/user/" + localStorage.uid,
      type: 'PUT',
      crossDomain: true,
      headers: {
          'X-CSRF-Token': token
      },
      contentType: 'application/json',
      data: JSON.stringify(userAccount)
    });

  }
});
7
  • You're pretty much the expert on this, so I'll test this and almost certainly accept your answer, haha.
    – Jack Ryan
    Commented Oct 20, 2017 at 23:10
  • Also I'm assuming I need a new token with each request?
    – Jack Ryan
    Commented Oct 23, 2017 at 23:13
  • No, you use the same token. Just have your application request a token upon startup, and after login/logout, and set the token aside, then you can use it for all subsequent requests. Commented Oct 24, 2017 at 14:43
  • I am getting a 401 unauthorized CSRF validation failed but only from my mobile device. What could possibly be causing that? I've temporarily given permission to create files to everyone, including anonymous to test this and it still won't work. It is happening on file creation.
    – Jack Ryan
    Commented Oct 26, 2017 at 23:04
  • I'd recommend trying to fetch a new token right before making the POST call, just to see if that gets it to work. It sounds like the token being sent up has expired. Commented Oct 27, 2017 at 14:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.