【问题标题】:Upload Base64 Image Facebook Graph API上传 Base64 图片 Facebook Graph API
【发布时间】:2013-04-19 07:42:18
【问题描述】:

我正在尝试使用 Node.js 将 base64 图像上传到 Facebook 页面。如果我从文件系统读取文件(即使用 fs.readFileSync('c:\a.jpg')

但是,我是否应该使用 base64 编码的图像并尝试上传它,它会给我以下错误:{"error":{"message":"(#1) An unknown error occurred","type":"OAuthException","code":1}}

我尝试通过new Buffer(b64string, 'base64'); 将其转换为二进制并上传,但没有成功。

我已经为此苦苦挣扎了 3 天,因此将不胜感激。

编辑:如果有人也知道我如何将 base64 转换为二进制并成功上传,那也适用于我。

编辑:代码片段

var postDetails = separator + newlineConstant + 'Content-Disposition: form-data;name="access_token"' + newlineConstant + newlineConstant + accessToken + newlineConstant + separator;

postDetails = postDetails + newlineConstant + 'Content-Disposition: form-data; name="message"' + newlineConstant + newlineConstant + message + newlineConstant;

//Add the Image information
var fileDetailsString = '';
var index = 0;
var multipartBody = new Buffer(0);
images.forEach(function (currentImage) {
    fileDetailsString = fileDetailsString + separator + newlineConstant + 'Content-Disposition: file; name="source"; filename="Image' + index + '"' + newlineConstant + 'Content-Type: image/jpeg' + newlineConstant + newlineConstant;
    index++;

    multipartBody = Buffer.concat([multipartBody, new Buffer(fileDetailsString), currentImage]); //This is what I would use if Bianry data was passed in 

    currentImage = new Buffer (currentImage.toString('base64'), 'base64'); // The following lines are what I would use for base64 image being passed in (The appropriate lines would be enabled/disabled if I was using Binary/base64)
    multipartBody = Buffer.concat([multipartBody, new Buffer(fileDetailsString), currentImage]);
});

multipartBody = Buffer.concat([new Buffer(postDetails), multipartBody, new Buffer(footer)]);

【问题讨论】:

  • b64String 来自哪里?你确定它不是数据 URL 吗?如果您console.log(b64string),请显示一些示例数据。
  • 您能否提供通过javascript ajax上传base64的任何示例。
  • 大家好,很抱歉回复晚了……我已经离开了。它绝对不是数据 URL...这里是数据开头的 sn-p.../9j/4AAQSkZJRgABAQEASABIAAD/2wBDABcQERQRDhcUEhQaGBcbIjk @Brune 我已更新帖子以放置上传部分的 sn-p。多部分数据等都可以正常工作,因为当我传递了一个二进制图像时,它都可以 100% 工作,但是当我传递了一个 base64 图像时,它就不起作用了。
  • 这与 Node.js 有关系吗?我有 base64 图像数据,并且对 ajax 请求的结构感到震惊(标头和正文中应该包含什么)。我遇到了无效请求错误。 .

标签: javascript node.js facebook-graph-api encoding base64


【解决方案1】:

我希望这会很有用。通过仅在 javascript 的帮助下将照片上传到 FB,您可以使用以下方法。这里需要的东西是imageData(这是base64格式的图像)和mime类型。

try {
    blob = dataURItoBlob(imageData,mimeType);
} catch (e) {
    console.log(e);
}

var fd = new FormData();
fd.append("access_token",accessToken);
fd.append("source", blob);
fd.append("message","Kiss");

try {
   $.ajax({
        url:"https://graph.facebook.com/" + <<userID received on getting user details>> + "/photos?access_token=" + <<user accessToken>>,
        type:"POST",
        data:fd,
        processData:false,
        contentType:false,
        cache:false,
        success:function(data){
            console.log("success " + data);
        },
        error:function(shr,status,data){
            console.log("error " + data + " Status " + shr.status);
        },
        complete:function(){
            console.log("Ajax Complete");
        }
   });

} catch(e) {
    console.log(e);
}

function dataURItoBlob(dataURI,mime) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs

    var byteString = window.atob(dataURI);

    // separate out the mime component


    // write the bytes of the string to an ArrayBuffer
    //var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    // write the ArrayBuffer to a blob, and you're done
    var blob = new Blob([ia], { type: mime });

    return blob;
}

//编辑 AJAX 语法

【讨论】:

  • 你让它工作了吗?我无法得到正确的回应。对于dataURI,你是否删除了“data:image/png;base64”部分?
  • 是的。它工作正常。是的,当您发送“data:image/png;base64”部分进行 Blob 转换时,您必须删除它。
  • 天哪,钼。这行得通!在这里抱怨之前应该对其进行更多调整。你是个奇迹创造者!
  • 希望有人看到这个!我正在尝试同样的事情,但我似乎总是收到来自 Facebook 的错误消息,我的 FormData 显示空数组。有什么想法吗??!
  • 您收到什么错误??你的意思是说你的formdata没有传递给facebook??
【解决方案2】:

上面的代码不太适合我(type:"POST", 后缺少逗号,并且 blob 函数的数据 URI 报告错误。我得到以下代码在 Firefox 和 Chrome 中工作:

function PostImageToFacebook(authToken)
{
    var canvas = document.getElementById("c");
    var imageData  = canvas.toDataURL("image/png");
    try {
        blob = dataURItoBlob(imageData);
    }
    catch(e) {
        console.log(e);
    }
    var fd = new FormData();
    fd.append("access_token",authToken);
    fd.append("source", blob);
    fd.append("message","Photo Text");
    try {
        $.ajax({
            url:"https://graph.facebook.com/me/photos?access_token=" + authToken,
            type:"POST",
            data:fd,
            processData:false,
            contentType:false,
            cache:false,
            success:function(data){
                console.log("success " + data);
            },
            error:function(shr,status,data){
                console.log("error " + data + " Status " + shr.status);
            },
            complete:function(){
                console.log("Posted to facebook");
            }
        });
    }
    catch(e) {
        console.log(e);
    }
}

function dataURItoBlob(dataURI) {
    var byteString = atob(dataURI.split(',')[1]);
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ab], { type: 'image/png' });
}

这是 GitHub 上的代码 https://github.com/DanBrown180/html5-canvas-post-to-facebook-base64

【讨论】:

  • 我已经尝试了您的代码,并且我与 Facebook 的通信似乎正常,但我有一个问题,即 fd (FormData) 为空,仅显示空数组。有什么想法吗?
【解决方案3】:

Dan's Answer 效果最好。在这种情况下可能有用的其他内容是发布照片的可选参数:'no_story'。此参数默认为 true 强制照片帖子跳过用户的墙。通过添加

fd.append("no_story", false);

您可以使用照片帖子更新用户的墙。

我本来只是把它作为评论留下,但是...... cmets 50 Rep。

【讨论】:

  • 这听起来很重要!嘿……你需要花更多的时间在这里!
【解决方案4】:

我们可以通过使用现代 Fetch API 而不是 Uint8Array 来简化图像重新编码。

 var url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="

 fetch(url)
  .then(res => res.blob())
  .then(blob => console.log(blob))`

【讨论】:

【解决方案5】:

我做了与你的问题非常相似的事情。我有一个需要发布到 Facebook 粉丝页面的网络摄像头快照。 设置在一家餐厅,人们可以在那里拍照,然后将其发布到餐厅页面上。然后,人们会看到发布的 Facebook 照片的二维码,他们可以选择在自己的个人资料中分享。 希望这可以帮助某人,因为我进行了很多搜索以找到这个可行的解决方案

注意:我的图片已经是 BASE64 编码的。

//imageData is a base64 encoded JPG
function postSocial(imageData, message){       
        var ia = toUInt8Array(imageData);
        postImageToFacebook(mAccessTokenPage, "imageName", "image/jpeg",ia, message);
}

function toUInt8Array(dataURI) {
        // convert base64 to raw binary data held in a string
        // doesn't handle URLEncoded DataURIs
        var byteString = window.atob(dataURI);

        // write the bytes of the string to an ArrayBuffer
        //var ab = new ArrayBuffer(byteString.length);
        var ia = new Uint8Array(byteString.length);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        return ia;
    }

function postImageToFacebook( authToken, filename, mimeType, imageData, message ) {        
        // this is the multipart/form-data boundary we'll use
        var boundary = '----ThisIsTheBoundary1234567890';

        // let's encode our image file, which is contained in the var
        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';

        var xhr = new XMLHttpRequest();
        xhr.open( 'POST', https://graph.facebook.com/ + {PAGE_ID} + "/photos?access_token=" + authToken, true );
        xhr.onload = function() {
            // ... Fill in your own
            //Image was posted 
           console.log(xhr.responseText);
        };
        xhr.onerror = function(){
            console.log("Error while sending the image to Facebook");
        };
        xhr.setRequestHeader( "Content-Type", "multipart/form-data; boundary=" + boundary );
        xhr.sendAsBinary( formData );
    }

【讨论】:

    【解决方案6】:

    以下是我如何使用 facebook JS API 将图像发布到 facebook。 我正在使用画布 HTML5 功能。并非每个浏览器都完全支持它。

    您首先需要获取图像数据。然后将其封装在表单数据中。 然后我使用 FB.login API 来检索访问令牌和用户 ID。

              var data = $('#map >> canvas').toDataURL('image/png');
              var blob;
              try {
                var byteString = atob(data.split(',')[1]);
                var ab = new ArrayBuffer(byteString.length);
                var ia = new Uint8Array(ab);
                for (var i = 0; i < byteString.length; i++) {
                  ia[i] = byteString.charCodeAt(i);
                }
                blob = new Blob([ab], {type: 'image/png'});
              } catch (e) {
                console.log(e);
              }
              var fd = new FormData();
              fd.append("source", blob);
              fd.append("message", "Photo Text");
              FB.login(function(){
                var auth = FB.getAuthResponse();
                $.ajax({
                  url:"https://graph.facebook.com/"+auth.userID+"/photos?access_token=" + auth.accessToken,
                  type:"POST",
                  data:fd,
                  processData:false,
                  contentType:false,
                  cache:false,
                  success:function(data){
                    console.log("success " + data);
                  },
                  error:function(shr,status,data){
                    console.log("error " + data + " Status " + shr.status);
                  },
                  complete:function(){
                    console.log("Ajax Complete");
                  }
                });
              }, {scope: 'publish_actions'});
    

    【讨论】:

    • 这很好,因为您向我们展示了如何获取实际的授权参数以联系 Facebook。
    【解决方案7】:

    这里是一个不需要 jQuery 或其他库的示例,只需要原生 Fetch API:

    const dataURItoBlob = (dataURI) => {
        let byteString = atob(dataURI.split(',')[1]);
        let ab = new ArrayBuffer(byteString.length);
        let ia = new Uint8Array(ab);
        for (let i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        return new Blob([ia], {
            type: 'image/jpeg'
        });
    }
    const upload = async (response) => {
        let canvas = document.getElementById('canvas');
        let dataURL = canvas.toDataURL('image/jpeg', 1.0);
        let blob = dataURItoBlob(dataURL);
        let formData = new FormData();
        formData.append('access_token', response.authResponse.accessToken);
        formData.append('source', blob);
    
        let responseFB = await fetch(`https://graph.facebook.com/me/photos`, {
            body: formData,
            method: 'post'
        });
        responseFB = await responseFB.json();
        console.log(responseFB);
    };
    document.getElementById('upload').addEventListener('click', () => {
        FB.login((response) => {
            //TODO check if user is logged in and authorized publish_actions
            upload(response);
        }, {scope: 'publish_actions'})
    })
    

    来源:http://www.devils-heaven.com/facebook-javascript-sdk-photo-upload-from-canvas/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多