Drupal Services File Create Example with JSON and JQuery
Note, please read about this issue with the Services module before getting started!
UPDATE: There is security issue with the Services module prior to version 3.4. Now all autheticated service calls that use POST, PUT or DELETE need a CSRF token sent along in the request header. This article has NOT been udpated to show those changes! More Information and Workaround(s)
Here is some example javascript that can be used to create a new file by using the File Create resource from the Services module in Drupal.
In this example, we'll be taking a base 64 encoded image string in javascript, deciding its file name and path to save in Drupal.
var data = { "file":{ "file":my_base_64_encoded_image_string, "filename":"my_image.jpg", "filepath":"sites/default/files/my_image.jpg", /* in D7 change this value to "public://my_image.jpg" */ } };
Next we'll build our ajax options and make the call to our services endpoint and corresponding file create resource...
options = { type:"post", data:data, url: Drupal.settings.basePath + 'my_services_endpoint/file.json', dataType: 'json', success:function(result){ console.log(JSON.stringify(result)); } }; $.ajax(options);
When it is successful, and we will be, the 'result' variable will contain the new Drupal file id and uri.
{ "fid":123, "uri":"http://www.example.com/my_services_endpoint/file/123" }
Now get out there and make me proud, create some image files in Drupal gosh darn it!
Note, if you're not using jQuery, and just using a JS XHR, then you must JSON.stringify(data) before sending it!
Comments
Tao (not verified)
Mon, 09/24/2012 - 19:02
Permalink
I cannot change the filepath
I cannot change the filepath to any subfolder such as sites/default/files/images/. all files r listed under the files folder. Can you give me some help? Thanks a lot.
tyler
Wed, 10/03/2012 - 12:56
Permalink
I would imagine if you change
I would imagine if you change the "filepath" value in the "data" variable in javascript to the directory of your choice, that should work. I haven't tried to save it anywhere but the sites/default/files directory. Also, I would check to make sure the directory you are trying to write to exists and has the proper write permissions.
Milorad (not verified)
Wed, 12/12/2012 - 06:15
Permalink
Hi Tyler,I am using rest
Hi Tyler,
I am using rest services in drupal 7 to upload images from iOs to drupal site. I am facing issue when trying to upload image larger than 800kB (content length of request is nearly 1 000 000 characters).
I have already posted question on http://drupal.org/node/1862478 .
Can you please take look at it and give your thoghts.
Thanks,
Milorad
tyler
Thu, 12/13/2012 - 11:13
Permalink
Hi Milorad,I'm sorry, I haven
Hi Milorad,
I'm sorry, I haven't run into this issue. But I'm sure it is real. I've always thought what is the limitation for the string length. In the past, I've just compressed the image quality down before sending it along so the string isn't so huge. I'll have to defer to the Services module team for specifics though.
Bilhip (not verified)
Thu, 12/13/2012 - 10:53
Permalink
What do you mean "my_base_64
What do you mean "my_base_64_encoded_image_string" ؟
thx :)
tyler
Thu, 12/13/2012 - 11:11
Permalink
Hi Bilhip,Basically, it is a
Hi Bilhip,
Basically, it is a giant string that represents an image, and that's what the File Create Service Resource needs. There are techniques to get a base 64 encoded string of an image in javascript, hope this google search helps.
Bilhip (not verified)
Thu, 12/13/2012 - 15:01
Permalink
Hi tyler .. i used poster in
Hi tyler .. i used poster in firefox ... but don't work
tyler
Tue, 12/18/2012 - 14:40
Permalink
Here are some suggestions
Here are some suggestions:
tyler
Thu, 02/01/2018 - 15:18
Permalink
I found myself struggling
I found myself struggling with this today, and it worked by removing the e.g. "data:image/png;base64," from the front of the "file" attribute.
Here's a little JS snippet to do it:
Aaron (not verified)
Thu, 01/17/2013 - 14:30
Permalink
Tyler, thanks for all your
Tyler, thanks for all your hard work on Drupalgap. I've been working with it to set up an app over the past week and although I've hit some speed bumps, the Drupal Services part of it has been one of the easiest parts because of your tutorials.
I'm trying to capture photos to associate with a node now, and I'm wondering if you had any thoughts on how to properly do this? Would you put an upload photo button on the node create screen much like Drupal's desktop interface, then associate the returned URL with the node? Run everything on submit and make the user wait on the file uploading, then the node create?
tyler
Wed, 02/20/2013 - 17:23
Permalink
Hi Aaron, Thank you for the
For other projects, I've put the 'add photo' button on the node edit screen of the app. Then used the File Create resource to create the file, then use the Node Update resource to attach the new file id to the node's image field. They key is associating just the file id with the field on your node.
Soon (soon-ish), DrupalGap will support filefield and images, so this will be pretty easy to accomplish. It still needs some more fine tuning, but if you check out the 7.x-1.x-dev version of the mobile app development kit on Github, that will shed some light on it.
Cameron (not verified)
Fri, 01/25/2013 - 09:41
Permalink
Hey Tyler -- how exactly
Hey Tyler -- how exactly would we attach a file to a node? Would the same procedure apply to attaching an image to a node or a user, should that field be exposed properly?
tyler
Wed, 02/20/2013 - 17:24
Permalink
Hi Cameron,Please see my
Hi Cameron,
Please see my reply to Aaron above, it should cover most of the points.
I've had this request so many times, I really want to write a blog post about just this topic. One of these days...
Guillermo (not verified)
Thu, 02/28/2013 - 07:25
Permalink
Just what I was looking.
Just what I was looking. Thanks for the example!!
nicole (not verified)
Sun, 04/14/2013 - 23:31
Permalink
Hi, may i know how did you
Hi, may i know how did you get your my_base_64_encoded_image_string?
tyler
Mon, 04/15/2013 - 09:57
Permalink
Hi Nicole,For my particular
Hi Nicole,
For my particular use case, I was using PhoneGap's camera feature, which automatically returns a base 64 encoded string to me. I would need to know more about your use case to help, hopefully this will point you in the right direction: https://www.google.com/search?q=how+to+base64+encode+an+image
Saneesh (not verified)
Tue, 06/07/2016 - 07:18
Permalink
Hello,
Hello,
"my_base_64_encoded_image_string" means you have to pass the base64 encoded string as the image file.
Reference: http://stackoverflow.com/a/11246772
Hope This Helps!
//San.
sreekanth chand... (not verified)
Thu, 04/18/2013 - 03:12
Permalink
Hi tyler, Thanks for
Hi tyler,
Thanks for writing detailed articles. All these are very helpful .
In my case am able to upload image to files after uploading i need to add that image to my content type. There in webservice what i need to specify
Please help me out.
Thanks in advance.
tyler
Thu, 04/18/2013 - 10:03
Permalink
You will use the Node Create
You will use the Node Create and/or Update service resource. Once you have the file id from the File Create resource, you can then pass that file id along with your Content Type's field.
For example, this would be the data string to send to the Node Create resource to create a new Article node and attach the new image to the article's image field:
David (not verified)
Tue, 04/29/2014 - 06:05
Permalink
hi, I'm really stuck with
hi, I'm really stuck with this; I'm uploading an image file and getting the fid but the subsequent request to create a node and attach the fid fails. The node is create although the image field is not filled in with the image fid and the image is not attached to the node.
I use this ajax to post the node:
Im getting this error:
Notice: Undefined offset: 0 in image_field_widget_form() (line 358 of /var/www/dt11/modules/image/image.field.inc).
Notice: Undefined offset: 0 in file_field_widget_form() (line 526 of /var/www/dt11/modules/file/file.field.inc).
Has anyone faced this before ? Any suggestions are highly appreaciated.
tyler
Tue, 04/29/2014 - 09:16
Permalink
Try removing the 'und'
Try removing the 'und' language code from the file field data string.
Also, try creating a node with an image on your site, then use Firefox Poster and GET on /my_endpoint/node/123.json, then copy/paste the JSON into jsonlint.com, examine the exact structure that is expected for the image field, then build your data query string to match it.
sreekanth (not verified)
Wed, 04/24/2013 - 06:18
Permalink
Hi tylerThanks for your quick
Hi tyler
Thanks for your quick response. When am trying to upload image
Am getting following callback error.. I culdnt able to get the sollution please help out.
tyler
Thu, 04/25/2013 - 09:34
Permalink
I see your code has a
I see your code has a reference to cordova-1.5.0.js, you should probably upgrade to the latest version (2.6 as of today). It looks like your code is missing the cordova-1.5.0.js file, or is referencing it incorrectly. Either way, upgrading to the latest version may fix the issue.
VG (not verified)
Thu, 04/25/2013 - 12:29
Permalink
Hi We are trying to upload a
Hi
We are trying to upload a picture using phonegap's camera API And then link it to a node of particular content type using Drupal 7 services 3. Here is the code:
For this, am getting a null error and not sure why.
tyler
Mon, 05/06/2013 - 19:36
Permalink
Sorry, I'm not sure what is
Sorry, I'm not sure what is going on there. I would check my Drupal watchdog listing right after attempting the upload. I would also use the Devel module's dpm() function on the file create resource code inside the Services module to see what is going on.
I've also added a note about an issue with the Services module. That may be what is causing your issue: http://drupal.org/node/1666748
sreekanth chand... (not verified)
Fri, 04/26/2013 - 03:45
Permalink
Image sucessfuly uploaded in
Image sucessfuly uploaded in to the server but when i try to open it its saying it is invalid image format.. Here is the image data am sending to the sever
{"uid":"1","filesize":"99999","filename":"whatever.jpg","file":"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2 .............."}
tyler
Mon, 05/06/2013 - 19:38
Permalink
Please see my reply above for
Please see my reply above for more information, it may be helpful for this issue as well.
Haroon (not verified)
Tue, 09/24/2013 - 16:47
Permalink
Hi Tylor!
Hi Tylor!
Nice Tutorial, I got a problem when i try to save the image using the services "Could not write file to destination". Please give me an idea what is causing this error?
And please can you provide sample code for above tutorial (D7).
Thanks.
tyler
Thu, 09/26/2013 - 13:50
Permalink
Hello Haroon,The example code
Hello Haroon,
The example code above does contain the D7 code, it is hard to see though. The first block of code has the D7 version, but the code is nested in a comment:
Just use "public://my_image.jpg" for the filepath and you should be all set.
Vamshidhar (not verified)
Thu, 02/20/2014 - 11:01
Permalink
Hi Tyler, thanks for the post
Hi Tyler, thanks for the post. I just want to know whether we can get multiple fid's with single call to file.json? Basically I want to include two files and send to file.json, and get two fid's.
tyler
Fri, 02/21/2014 - 09:42
Permalink
I don't think you can POST
I don't think you can POST more than one file at a time. If I were going to try it, I would POST a JSON object (or maybe an array) via the application/json Content-Type. The object/array would then contain multiple "file" JSON object that are equivalent to the ?data url.
Marcus VBP (not verified)
Sun, 08/17/2014 - 06:05
Permalink
How to create the file inside
How to create the file inside the "files" folder?
After successul post to Drupal.settings.basePath + 'my_services_endpoint/file.json' the retorned URI give all image data in base64 format, uri_full, filename etc, but the file is not created in the disk inside the files folder.
I think I can do this using create_raw but I can not make it work. I do not know how to pass parameters, or what parameters to pass.
tyler
Sun, 08/17/2014 - 12:01
Permalink
I haven't used the create raw
I haven't used the create raw service resource. I'd recommend posting a Support Request in the Services module's issue queue.
After POSTing to the file.json endpoint, you should get get back the file id and uri, if it is returning anything other than that, then it's probably being used incorrectly.
DAYS (not verified)
Wed, 01/14/2015 - 23:23
Permalink
Uncaught ReferenceError: edit
Stuart Dotson (not verified)
Sun, 06/21/2015 - 16:01
Permalink
Is there an updated version
Is there an updated version of the code taking into account the CSRF token? I've been trying to get this to work for days. Also how do you get the base64 image string? Say you have a file input in a custom form you built and you just want to upload an image into drupal?
tyler
Mon, 06/22/2015 - 08:21
Permalink
As linked above, here's an
As linked above, here's an example Drupal comment showing how to get the token, then making a POST call: https://www.drupal.org/node/2013781#comment-7507759
Jigar Mehta (not verified)
Fri, 05/20/2016 - 10:17
Permalink
I can attach files, however,
I can attach files, however, how do I detach files? Say, I have field_image on the user account entity. How do I unlink that file id from my user object?
tyler
Fri, 05/20/2016 - 10:24
Permalink
Maybe send a null fid. This
Maybe send a null fid. This issue may be related: https://www.drupal.org/node/2224803
Selcy (not verified)
Wed, 01/18/2017 - 05:54
Permalink
Hi Tyler, do you know how to
Hi Tyler, do you know how to download a file using Drupal private files system? I'm trying cordova app, but i´m stuck cause I get the user session correctly but the download doesn't works. Thanks a lot, I appreciate your help so much.
Regards
tyler
Wed, 01/18/2017 - 09:24
Permalink
I do not, I haven't ever
I do not, I haven't ever needed a private file system on a Drupal site in almost 10 years of working with Drupal.
Christian (not verified)
Tue, 04/25/2017 - 18:11
Permalink
Hi Tyler,
Hi Tyler,
Great post!!
How do you create an image and pass the alternate text along? I don't think it's possible but just want to make sure.
Thank you
tyler
Wed, 04/26/2017 - 09:15
Permalink
It should be possible, I
It should be possible, I think you'll just pass it along with the file id when you're done: