javascript - net - php facebook api




Facebook Graph API-使用JavaScript上傳照片 (9)

編輯:這個答案(現在)基本上無關緊要。 如果您的圖片在網絡上,只需根據API指定url參數(並參閱其他答案中的示例)。 如果您想直接將圖像內容髮佈到Facebook,您可能需要閱讀此答案以獲得理解。 另請參閱HTML5的Canvas.toDataUrl()

API API :“要發布照片, 請將照片文件附件作為multipart / form-data發出POST請求。”

FB期望要上傳的圖像的字節位於HTTP請求的正文中,但它們不在那裡。 或者以另一種方式看待它 - 在FB.api()調用中你在哪裡提供圖像本身的實際內容?

FB.api() API文檔很少,並沒有提供包含正文的HTTP POST示例。 人們可能會因缺乏這樣的例子而推斷它不支持這一點。

這可能沒關係 - FB.api()正在使用一個名為XmlHttpRequest東西, 支持包括一個正文...在你最喜歡的JavaScript參考中查找它。

但是,您仍然需要解決2個子問題:

  1. 如何將圖像字節(以及請求的其餘部分)準備為multipart/form-data ; 和
  2. 獲取圖像本身的字節

(順便說一句,編碼消息體的需要可能是PHP setFileUploadSupport(true)方法的用途 - 告訴facebook對像在發送之前將消息體編碼為multipart/form-data

但它有點不合理

不幸的是,子問題'2'可能會咬你 - 我沒辦法(上次看)從瀏覽器提供的Image對像中提取圖像的字節。

如果要通過URL訪問要上載的圖像,則可以使用XmlHttpRequest獲取字節。 還不錯。

如果圖像來自用戶的桌面,您可能的辦法是為用戶提供:

 <form enctype="multipart/form-data">
     <input type="filename" name="myfile.jpg" />
     <input type="hidden" name="source" value="@myfile.jpg"/>
     <input type="hidden" name="message" value="My Message"/>
     <input type="hidden" name="access_token" value="..."/> 
 </form> 

(注意source引用了給文件上傳小部件的名稱)

...並希望FB預期以這種方式接收數據(首先嘗試使用靜態HTML表單,然後在JS中動態編碼)。 有人可能會推斷,事實上它會,因為他們沒有提供另一種方法。

是否可以使用javascript使用Facebook Graph API上傳文件,我覺得我很接近。 我正在使用以下JavaScript

var params = {};
params['message'] = 'PicRolled';
params['source'] = '@'+path;
params['access_token'] = access_token;
params['upload file'] = true;

function saveImage() {
    FB.api('/me/photos', 'post', params, function(response) {
        if (!response || response.error) {
            alert(response);
        } else {
            alert('Published to stream - you might want to delete it now!');
        }
    }); 
}

運行此操作後,我收到以下錯誤...

"OAuthException" - "(#324) Requires upload file"

當我嘗試研究這種方法時,我所能發現的是一種能夠解決這個問題的php方法

$facebook->setFileUploadSupport(true);

但是,我使用JavaScript,看起來這種方法可能與Facebook Graph權限有關,但我已經設置了權限user_photos和publish_stream,我認為這是我應該執行此操作的唯一權限。

我已經在stackoverflow上看到了一些關於這個的未解答的問題,希望我能夠解釋自己。 多謝你們。


可以使用Ajax將照片上傳到Facebook個人資料,如下所示。

$.ajax({
            type: "POST",
            url: "https://graph.facebook.com/me/photos",
            data: {
                message: "Your Msg Goes Here",
                url: "http://www.knoje.com/images/photo.jpg[Replace with yours]",
                access_token: token,
                format: "json"
            },
            success: function(data){
               alert("POST SUCCESSFUL"); }
            });

因此,這是使用GRAPH API將照片發佈到Facebook個人資料的最佳方式,這是一個簡單的方法。

在許多答案中,我已經看到圖像網址是源,圖片或圖像等,但這不起作用。

使用源,圖片或圖像會導致(#324)需要上傳文件錯誤。

避免324錯誤的最佳方法。


https://.com/a/16439233/68210包含一個解決方案,如果您需要上傳照片數據本身並且沒有網址,則該解決方案有效。


只有@Thiago的回答是回答通過javascript 上傳數據的問題。 我發現Facebook JS API沒有涵蓋這種情況。

我也在釀造和測試我的個人解決方案。

主要步驟

  1. 獲取圖像的二進制數據(我使用了畫布,但也可以使用輸入框)
  2. 形成包含圖API調用的所有necesarry數據的多部分請求
  3. 在請求中包含二進制數據
  4. 對二進制數組中的所有內容進行編碼,然後通過XHR發送

轉換工具

var conversions = {
  stringToBinaryArray: function(string) {
    return Array.prototype.map.call(string, function(c) {
      return c.charCodeAt(0) & 0xff;
    });
  },
  base64ToString: function(b64String) {
    return atob(b64String);
  }
};

圖片發布片段

var DEFAULT_CALL_OPTS = {
  url: 'https://graph.facebook.com/me/photos',
  type: 'POST',
  cache: false,
  success: function(response) {
    console.log(response);
  },
  error: function() {
    console.error(arguments);
  },
  // we compose the data manually, thus
  processData: false,
  /**
   *  Override the default send method to send the data in binary form
   */
  xhr: function() {
    var xhr = $.ajaxSettings.xhr();
    xhr.send = function(string) {
      var bytes = conversions.stringToBinaryArray(string);
      XMLHttpRequest.prototype.send.call(this, new Uint8Array(bytes).buffer);
    };
    return xhr;
  }
};
/**
 * It composes the multipart POST data, according to HTTP standards
 */
var composeMultipartData = function(fields, boundary) {
  var data = '';
  $.each(fields, function(key, value) {
    data += '--' + boundary + '\r\n';

    if (value.dataString) { // file upload
      data += 'Content-Disposition: form-data; name=\'' + key + '\'; ' +
        'filename=\'' + value.name + '\'\r\n';
      data += 'Content-Type: ' + value.type + '\r\n\r\n';
      data += value.dataString + '\r\n';
    } else {
      data += 'Content-Disposition: form-data; name=\'' + key + '\';' +
        '\r\n\r\n';
      data += value + '\r\n';
    }
  });
  data += '--' + boundary + '--';
  return data;
};

/**
 * It sets the multipart form data & contentType
 */
var setupData = function(callObj, opts) {
  // custom separator for the data
  var boundary = 'Awesome field separator ' + Math.random();

  // set the data
  callObj.data = composeMultipartData(opts.fb, boundary);

  // .. and content type
  callObj.contentType = 'multipart/form-data; boundary=' + boundary;
};

// the "public" method to be used
var postImage = function(opts) {

  // create the callObject by combining the defaults with the received ones
  var callObj = $.extend({}, DEFAULT_CALL_OPTS, opts.call);

  // append the access token to the url
  callObj.url += '?access_token=' + opts.fb.accessToken;

  // set the data to be sent in the post (callObj.data = *Magic*)
  setupData(callObj, opts);

  // POST the whole thing to the defined FB url
  $.ajax(callObj);
};

用法

postImage({
  fb: { // data to be sent to FB
    caption: caption,
    /* place any other API params you wish to send. Ex: place / tags etc.*/
    accessToken: 'ACCESS_TOKEN',
    file: {
      name: 'your-file-name.jpg',
      type: 'image/jpeg', // or png
      dataString: image // the string containing the binary data
    }
  },
  call: { // options of the $.ajax call
    url: 'https://graph.facebook.com/me/photos', // or replace *me* with albumid
    success: successCallbackFunction,
    error: errorCallbackFunction
  }
});

額外

提取畫布圖像的二進製字符串表示

var getImageToBeSentToFacebook = function() {
  // get the reference to the canvas
  var canvas = $('.some-canvas')[0];

  // extract its contents as a jpeg image
  var data = canvas.toDataURL('image/jpeg');

  // strip the base64 "header"
  data = data.replace(/^data:image\/(png|jpe?g);base64,/, '');

  // convert the base64 string to string containing the binary data
  return conversions.base64ToString(data);
}

有關如何從input[type=file]加載binaryString的信息

HTML5文件API讀作文本和二進製文件

筆記:

  1. 當然也有替代方法
    • 在iframe中使用HTML表單 - 您無法從通話中獲得響應
    • 使用FormDataFile方法,但遺憾的是在這種情況下有很多不兼容性使得這個過程更難以使用,你最終會在不一致的情況下使用管道 - 因此我的選擇是手動數據組裝,因為HTTP標準很少改變:)
  2. 該解決方案不需要任何特殊的HTML5功能。
  3. 上面的例子使用了jQuery.ajaxjQuery.extendjQuery.each

我似乎有類似的問題,但上面的解決方案不起作用。

我正在使用Arrabi建議的解決方案(僅使用url屬性)發布圖像沒有任何問題。 我的圖像大約每個2-3 MB。

當我將我的應用程序遷移到另一台服務器(在帖子中更改我的圖像的絕對URL)時,該方法為大約100k大小的圖像提供了324錯誤。

我認為這是由於我的一些Apache設置,但當我為lighttpd更改apache時,問題仍然存在。

來自Facebook的連接實際上顯示在我的(apache)日誌中:

69.171.234.7 - - [08 / Jun / 2012:11:35:54 +0200]“GET /images/cards/1337701633_518192458.png HTTP / 1.1”200 2676608“ - ”“facebookplatform / 1.0(+ http://開發人員.facebook.com)“

69.171.228.246 - - [08 / Jun / 2012:11:42:59 +0200]“GET /images/test5.jpg HTTP / 1.1”200 457402“ - ”“facebookplatform / 1.0(+ http://developers.facebook .COM)“

69.171.228.246 - - [08 / Jun / 2012:11:43:17 +0200]“GET /images/test4.jpg HTTP / 1.1”200 312069“ - ”“facebookplatform / 1.0(+ http://developers.facebook .COM)“

69.171.228.249 - - [08 / Jun / 2012:11:43:49 +0200]“GET /images/test2.png HTTP / 1.1”200 99538“ - ”“facebookplatform / 1.0(+ http://developers.facebook .COM)“

69.171.228.244 - - [08 / Jun / 2012:11:42:31 +0200]“GET /images/test6.png HTTP / 1.1”200 727722“ - ”“facebookplatform / 1.0(+ http://developers.facebook .COM)“

只有test2.png成功了。


我使用@ВладимирДворник代碼進行了一些修改,我有同樣的問題,並且使用此代碼它運行得非常好:

        var imgURL = //your external photo url
        FB.api('/photos', 'post', {
            message: 'photo description',
            access_token: your accesstoken 
            url: imgURL
        }, function (response) {

            if (!response || response.error) {
                alert('Error occured:' + response);
            } else {
                alert('Post ID: ' + response.id);
            }

        });

是的,你可以像here一樣將數據發佈到iframe,或者你可以使用jQuery文件上傳 。 問題是你無法從iframe獲得響應,使用插件可以使用頁面句柄。

示例:使用jQuery文件上載上傳視頻

<form id="fileupload" action="https://graph-video.facebook.com/me/photos" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="acess_token" value="user_acess_token">
    <input type="text" name="title">
    <input type="text" name="description">
    <input type="file" name="file"> <!-- name must be file -->
</form>


<script type="text/javascript">

    $('#fileupload').fileupload({
        dataType: 'json',
        forceIframeTransport: true, //force use iframe or will no work
        autoUpload : true,
        //facebook book response will be send as param
        //you can use this page to save video (Graph Api) object on database
        redirect : 'http://pathToYourServer?%s' 
    });
</script>

是的,這是可能的,我找到2個解決方案如何做到這一點,它們彼此非常相似,你只需要將url參數定義到外部圖像網址

第一個使用Javascript SDk:

var imgURL="http://farm4.staticflickr.com/3332/3451193407_b7f047f4b4_o.jpg";//change with your external photo url
FB.api('/album_id/photos', 'post', {
    message:'photo description',
    url:imgURL        
}, function(response){

    if (!response || response.error) {
        alert('Error occured');
    } else {
        alert('Post ID: ' + response.id);
    }

});

SECOND一個使用jQuery Post請求和FormData:

 var postMSG="Your message";
 var url='https://graph.facebook.com/albumID/photos?access_token='+accessToken+"&message="+postMSG;
 var imgURL="http://farm4.staticflickr.com/3332/3451193407_b7f047f4b4_o.jpg";//change with your external photo url
 var formData = new FormData();
 formData.append("url",imgURL);

  $.ajax({
                    url: url,
                    data: formData,
                    cache: false,
                    contentType: false,
                    processData: false,
                    type: 'POST',

                    success: function(data){
                        alert("POST SUCCESSFUL");
                    }
                });

這仍然有效。 我正在使用它如下:

var formdata= new FormData();
if (postAs === 'page'){
    postTo = pageId; //post to page using pageID
}

formdata.append("access_token", accessToken); //append page access token if to post as page, uAuth|paAuth
formdata.append("message", photoDescription);
formdata.append("url", 'http://images/image.png');

try {
    $.ajax({
        url: 'https://graph.facebook.com/'+ postTo +'/photos',
        type: "POST",
        data: formdata,
        processData: false,
        contentType: false,
        cache: false,
        error: function (shr, status, data) {
            console.log("error " + data + " Status " + shr.status);
        },
        complete: function () {
            console.log("Successfully uploaded photo to Facebook");
        }
    });
} catch (e) {
    console.log(e);
}

我不得不問,如果你有人知道這是否可行,或者與使用PHP api for Facebook相比具有很大的安全風險。







file-upload