Facebook Graph API – 使用JavaScript上传照片
是否有可能使用JavaScript上传使用FacebookgraphicsAPI的文件,我觉得我很接近。 我正在使用下面的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"
当我尝试和研究这个方法时,我所能find的是一个可以解决这个问题的php方法
$facebook->setFileUploadSupport(true);
不过,我正在使用JavaScript,它看起来像这个方法可能是与Facebook Graph权限,但我已经设置了权限user_photos和publish_stream,我相信是我应该需要执行此操作的唯一的。
我已经看到了几个关于这个在stackoverflow上没有回答的问题,希望我可以解释自己。 多谢你们。
编辑:这个答案是(现在)在很大程度上不相关。 如果您的图片位于networking上,只需按照API指定
url
参数(并参阅其他答案中的示例)。 如果您想直接将图像内容发布到Facebook,您可能需要阅读此答案以获得理解。 另请参阅HTML5的Canvas.toDataUrl()
。
该API 说 :“要发布一张照片,发出一个带有照片文件附件的POST请求作为multipart / form-data 。
FB期望要上载的图像的字节在HTTP请求的主体中,但是它们不在那里。 或者以另一种方式来看待它 – 在FB.api()调用中,您提供图像本身的实际内容?
FB.api() APIlogging不完整,不提供包含主体的HTTP POST示例。 从没有这样的例子可以推断,它不支持这个。
这可能是确定的 – FB.api()在封面下使用了一些名为XmlHttpRequest
东西, 它支持包括一个主体…查看你最喜欢的JavaScript引用。
不过,你仍然有两个子问题需要解决:
- 如何将图像字节(以及其余的请求)准备为多部分/表单数据 ; 和
- 获取图像本身的字节
(顺便说一下,编码消息正文的需要可能是PHP setFileUploadSupport(true)方法的用途 – 告诉facebook
对象在发送之前将消息正文编码为multipart/form-data
)
但是比这更有趣
不幸的是,子问题'2'可能咬你 – 没有办法(上次我看)从浏览器提供的图像对象提取图像的字节。
如果要上传的图像可以通过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
引用了file upload小部件的名称)
…并希望FB预期以这种方式接收数据(先用静态HTML表单试用,然后再用JSdynamic编码)。 有人可能会推断,实际上,因为他们没有提供另一种手段。
是的,这是可能的,我find了2个解决scheme如何做到这一点,他们是非常相似的,你只需要定义url参数外部图像url
第一个使用Javascript SDK:
var imgURL="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); } });
第二个使用jQuery Post请求和FormData:
var postMSG="Your message"; var url='https://graph.facebook.com/albumID/photos?access_token='+accessToken+"&message="+postMSG; var imgURL="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 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); } });
照片可以使用Ajax上传到Facebook个人资料,如下所示。
$.ajax({ type: "POST", url: "https://graph.facebook.com/me/photos", data: { message: "Your Msg Goes Here", url: "http://www.knoje.comhttp://img.dovov.comphoto.jpg[Replace with yours]", access_token: token, format: "json" }, success: function(data){ alert("POST SUCCESSFUL"); } });
所以这是使用GRAPH API将照片发布到Facebook个人资料的最好方法,也是最简单的一种。
在很多答案中,我已经看到,图像的URL是由源,图片或图像等,但不起作用。
源,图片或图像的使用导致(#324)需要上传文件错误。
最好的方法来避免324错误。
只有@ Thiago的答案是回答通过JavaScript 上传数据的问题。 我发现Facebook的JS API不包括这种情况。
我也酿造和testing了我的个人解决scheme。
主要步骤
- 获取图像的二进制数据(我使用了canvas,但也可以使用input框)
- 使用图API调用的所有必需数据形成多部分请求
- 在请求中包含二进制数据
- 将所有内容都编码为二进制数组,然后通过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 } });
额外
提取canvas图像的二进制string表示
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的信息input[type=file]
HTML5文件API读取为文本和二进制文件
笔记:
- 当然也有替代方法
- 在iframe中使用HTML表单 – 您无法从调用中获得响应
- 使用
FormData
&File
方法,但不幸的是,在这种情况下,会有很多不兼容的情况使得这个过程更难使用,而且最终会导致不一致的问题 – 因此,我的select是手动数据组装,因为HTTP标准很less改变:)
- 该解决scheme不需要任何特殊的HTML5function。
- 上面的例子使用了
jQuery.ajax
,jQuery.extend
,jQuery.each
是的,你可以把这个发布数据做到像这里一样的iframe,或者你可以使用jQueryfile upload 。 问题是你无法从iframe获得响应,使用插件你可以使用页面句柄。
例如:使用jQuery File Upload上传video
<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>
只需使用Javascript从本地计算机上传文件,请尝试HelloJS
<form onsubmit="upload();"> <input type="file" name="file"/> <button type="submit">Submit</button> </form> <script> function upload(){ hello.api("facebook:/me/photos", 'post', document.getElementById('form'), function(r){ alert(r&&!r.error?'Success':'Failed'); }); } </script>
这仍然有效。 我正在使用它如下:
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:/http://img.dovov.comimage.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); }
我不得不问,如果你有任何想法,如果这是可取的或有一个很大的安全风险相比,使用Facebook的PHP API。
这工作:
function x(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/me/photos?access_token=' + authToken, true); xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary); // Solving problem with sendAsBinary for chrome try { if (typeof XMLHttpRequest.prototype.sendAsBinary == 'undefined') { XMLHttpRequest.prototype.sendAsBinary = function(text) { var data = new ArrayBuffer(text.length); var ui8a = new Uint8Array(data, 0); for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff); this.send(ui8a); } } } catch (e) {} xhr.sendAsBinary(formData); };
我似乎有一个类似的问题,但上面的解决scheme不起作用。
我正在使用Arrabibuild议的解决scheme(只使用url属性)发布图像没有任何问题。 我的图像大约每个2-3 MB。
当我将我的应用程序迁移到另一台服务器(更改我的图像在文章中的绝对url),该方法不断给我以上约100k大小的图像324错误。
我认为这是由于我的一些Apache设置,但是当我改变了Apache的lighttpd问题仍然存在。
来自Facebook的连接实际上显示在我的(apache)日志中:
69.171.234.7 – – [08 / Jun / 2012:11:35:54 +0200]“GET http://img.dovov.comcards/1337701633_518192458.png HTTP / 1.1”200 2676608“ – ”“facebookplatform / 1.0(+ http:// developers .facebook.com)”
69.171.228.246 – [08 / Jun / 2012:11:42:59 +0200]“GET http://img.dovov.comtest5.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 http://img.dovov.comtest4.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 http://img.dovov.comtest2.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 http://img.dovov.comtest6.png HTTP / 1.1”200 727722“ – ”“facebookplatform / 1.0(+ http://developers.facebook .COM)”
只有test2.png成功。
我使用以下来分享照片(Phaser框架中的一些BitmapData)。 这似乎工作…
// Turn data URI to a blob ready for upload. dataURItoBlob(dataURI:string): Blob { 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/jpeg' }); } // Share the given bitmapData as a photo on Facebook sharePhoto(accessToken: string, photo: BitmapData, message: string): void { // Create form data, set up access_token, source and message var fd = new FormData(); fd.append("access_token", accessToken); fd.append("source", this.dataURItoBlob(photo.canvas.toDataURL("image/jpeg"))); fd.append("message", message); var request = new XMLHttpRequest(); var thisPtr = this; request.onreadystatechange = function () { if (request.readyState == XMLHttpRequest.DONE) { var json = JSON.parse(request.responseText); if (json.hasOwnProperty("error")) { var error = json["error"]; if (error.hasOwnProperty("type")) { var errorType = error["type"]; if (errorType === "OAuthException") { console.log("Need to request more permissions!"); } } } } else if (request.readyState == XMLHttpRequest.HEADERS_RECEIVED) { } else if (request.readyState == XMLHttpRequest.LOADING) { } else if (request.readyState == XMLHttpRequest.OPENED) { } else if (request.readyState == XMLHttpRequest.UNSENT) { } } request.open("POST", "https://graph.facebook.com/me/photos", true); request.send(fd); }
- 我可以使用Facebook API设置用户个人资料图片吗?
- 在Android上传video到Facebook
- 张贴到Facebook页面没有“manage_pages”权限使用PHP
- 应用程序被错误configuration为Facebooklogin:Android Facebook集成问题
- 脸谱图API不工作从2.2到2.3
- Python – Facebook的API – 需要一个工作的例子
- 没有loginbutton的Facebookauthentication
- 为什么Facebook的PHP SDK getUser总是返回0?
- XMPP与支持X-FACEBOOK-PLATFORM的Java Asmack库