【问题标题】:Using Facebooks javascript api to post multipart/form-data encoded image使用 Facebooks javascript api 发布多部分/表单数据编码图像
【发布时间】:2015-03-10 03:04:43
【问题描述】:

根据 Facebook 在用户照片边缘的 Graph 文档,可以使用 multipart/form-data 编码的二进制图像从 javascript 发布照片。 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 */
      }
    }
);

问题在于,网络上的任何地方似乎都没有任何示例文档说明这应该如何工作。有一种方法可以绕过 FB.api 并通过 xhr 请求直接发布到边缘。我已经让它工作了,但我真的很想知道如何使用 FB.api 命令来做到这一点。这是我的代码(FB 应用程序已正确注册,并且所有 javascript sdk 都包含在文件的其他位置):

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)
    });

};

方法#1:有效。我已经多次使用它来成功分享图像。在 Chrome 中查看网络控制台时,您可以看到 content-type:multipart/form-data 标头设置为该标头,然后它将所有数据放入“请求有效负载”中,并且返回响应是成功的帖子 ID。

方法#2:不起作用。 Facebook 返回的错误是(#324) Requires upload file。查看网络控制台,您可以看到设置了 content-type:application/x-www-form-urlencoded 标头(这是我们想要的)。该表单被放在表单数据下的“源”帖子参数下,这就是我假设它被 Facebook 拒绝的原因。

让 FB.api 在这里正常工作需要什么魔法?他们在文档中提供的唯一线索是指向 W3 关于 multipart/form-data 规范的链接,我知道我的 formData 符合该规范,因为它在方法 #1 中与 xhr 一起使用。除了 facebook 文档中的提及之外,我找不到任何实际工作的 javascript 方法示例。帮忙?

【问题讨论】:

  • 您是否有明确的理由不使用form data
  • 我调查了这个。它主要与缺乏 IE 兼容性(需要 10+)有关。在你研究了 polyfill 之后,我没有发现仅仅手动创建它有什么优势。
  • 我明白了。我将在今天晚些时候尝试调查该 api。
  • 什么是 Base64Binary 对象?
  • facebook 文档 suuuuuuuuuucks

标签: javascript facebook-graph-api multipartform-data


【解决方案1】:

我没有让它与官方 JS SDK(带有 FB.api)一起工作,但这是它通过文件输入轻松工作的方式:

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);

无需额外的插件,FileReader 和 fetch API 是原生 Javascript 功能。

如果输入是画布对象的 Base64 字符串,则可以使用:Creating a Blob from a base64 string in JavaScript

更多信息:http://www.devils-heaven.com/facebook-javascript-sdk-photo-upload-with-formdata/

【讨论】:

  • 谢谢。虽然我的问题已经 3 年了,而且我不再有源代码或应用程序 ID 来测试它,但我已将其标记为答案。有趣的是,一直到后来,其他人仍然无法让本机 FB.api 工作。
  • thanx,我在最近的一个项目中需要它,但官方 sdk 似乎仍然没有办法......不过,如果我发现了一个,我会更新它。它确实有效,而且代码不多,所以无论如何:)
猜你喜欢
  • 2017-06-06
  • 2016-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
  • 2012-04-17
  • 2014-11-21
  • 2014-08-06
相关资源
最近更新 更多