Using Facebooks javascript api to publish multi-file / form-encoded image

According to the Facebook Graph documentation on the edge of the user's photos, you can send a javascript photo using a binary image encoded in multipart / form-data. https://developers.facebook.com/docs/graph-api/reference/v2.2/user/photos

/* make the API call */ FB.api( "/me/photos", "POST", { "source": "{image-data}" }, function (response) { if (response && !response.error) { /* handle the result */ } } ); 

The problem is that in some network there is no sample documentation on how this should work. There is a method in which you bypass FB.api and send the message directly to the edge via an xhr request. I got this to work, but I would love to know how to do this using the FB.api command. Here is my code (the FB application was registered correctly, and all javascript sdk are included elsewhere in the file):

 function postImageToFacebook(authToken) { //Capture the image from a canvas var filename = "samplepic.png", mimeType = "image/png", message = "test comment", data = canvas.toDataURL("image/png"), encodedPng = data.substring(data.indexOf(',') + 1, data.length), imageData = Base64Binary.decode(encodedPng); // build the multipart/form-data var boundary = '----ThisIsTheBoundary1234567890'; var formData = '--' + boundary + '\r\n' formData += 'Content-Disposition: form-data; name="source"; filename="' + filename + '"\r\n'; formData += 'Content-Type: ' + mimeType + '\r\n\r\n'; for (var i = 0; i < imageData.length; ++i) { formData += String.fromCharCode(imageData[i] & 0xff); } formData += '\r\n'; formData += '--' + boundary + '\r\n'; formData += 'Content-Disposition: form-data; name="message"\r\n\r\n'; formData += message + '\r\n' formData += '--' + boundary + '--\r\n'; //METHOD #1: send the data using xhr request var xhr = new XMLHttpRequest(); xhr.open( 'POST', 'https://graph.facebook.com/me/photos?access_token=' + authToken, true ); xhr.onload = xhr.onerror = function() { console.log( xhr.responseText ); }; //vvv This right here seems to be key, being able to add a header vvv xhr.setRequestHeader( "Content-Type", "multipart/form-data; boundary=" + boundary ); xhr.sendAsBinary( formData ); //METHOD #2: send the data using FB.api FB.api("/me/photos", "POST", { "source": formData }, function(response) { console.log(response) }); }; 

Method # 1 : works. I used it several times to successfully share my image. When viewing the network console in Chrome, you can see the header content-type:multipart/form-data , in which it puts all the data in the "Request Payload", and the return response is a successful message identifier.

Method # 2 : does not work. The error returned by Facebook is (#324) Requires upload file . Looking at the network console, you can see that the header content-type:application/x-www-form-urlencoded set (this is what we do not want). The form is entered under the post-source parameter in Form Data, so I assume that it is rejected by Facebook.

What is the magic necessary for the correct operation of FB.api? The only key they give in their documents is a link to the W3 specification for multipart / form-data, which, as I know, matches my Data form, since it works with xhr in method # 1. Without mentioning facebook documents, I I can not find any example of this javascript method that really works. Help?

0
source share
1 answer

I did not get this to work with the official JS SDK (with FB.api), but this way it works easily with file input:

 const fileReader = new FileReader(); const file = document.getElementById('imageInput').files[0]; fileReader.onloadend = async () => { const photoData = new Blob([fileReader.result], {type: 'image/jpg'}); const formData = new FormData(); formData.append('access_token', pageAccessToken); formData.append('source', photoData); formData.append('message', 'some status message'); let response = await fetch(`https://graph.facebook.com/${pageId}/photos`, { body: formData, method: 'post' }); response = await response.json(); console.log(response); }; fileReader.readAsArrayBuffer(file); 

No additional plugin required, the FileReader and Fetch APIs are Javascript's own functions.

If the input is a Base64 string of the canvas object, you can use this: Creating a Blob from a base64 string in JavaScript

Additional information: http://www.devils-heaven.com/facebook-javascript-sdk-photo-upload-with-formdata/

+1
source

Source: https://habr.com/ru/post/1244586/


All Articles