Est-il possible de télécharger un fichier à l'aide de l'API Facebook Graph à l'aide de javascript, j'ai l'impression d'être proche. J'utilise le JavaScript suivant
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!');
}
});
}
En cours d'exécution, je reçois le message d'erreur suivant ...
"OAuthException" - "(#324) Requires upload file"
Quand j'essaie de faire des recherches sur cette méthode, je ne découvre qu'une méthode php qui permet de résoudre ce problème.
$facebook->setFileUploadSupport(true);
Cependant, j'utilise JavaScript. Il semble que cette méthode soit liée aux autorisations de Facebook Graph, mais j'ai déjà défini les autorisations user_photos et publish_stream, qui, à mon avis, sont les seules dont je devrais avoir besoin pour effectuer cette opération.
J'ai vu quelques questions sans réponse à ce sujet à propos du stackoverflow, j'espère pouvoir m'expliquer suffisamment. Merci les gars.
EDIT: cette réponse est (maintenant) largement hors de propos. Si votre image est sur le Web, spécifiez simplement le paramètre
url
conformément au API (et voyez des exemples dans d'autres réponses). Si vous souhaitez POST afficher directement le contenu de l'image sur Facebook, vous pouvez lire cette réponse pour mieux comprendre. Voir aussi la fonctionCanvas.toDataUrl()
de HTML5.
L'API dit : "Pour publier une photo, lancez une demande POST avec la pièce jointe du fichier photo sous forme de multipart/form-data."
FB s'attend à ce que les octets de l'image à télécharger figurent dans le corps de la demande HTTP, mais ils ne le sont pas. Ou bien, regardez-le sous un autre angle: où, dans l'appel FB.api (), fournissez-vous le contenu réel de l'image?
L'API FB.api () est mal documentée et ne fournit pas d'exemple de HTTP POST incluant un corps. On pourrait déduire de l'absence d'un tel exemple que cela ne le supporte pas.
C'est probablement OK - FB.api () utilise quelque chose appelé XmlHttpRequest
sous les couvertures que ne prend en charge, y compris un corps ... regardez-le dans votre référence JavaScript préférée.
Cependant, vous aurez toujours 2 problèmes secondaires à résoudre:
(incidemment, la nécessité de coder le corps du message correspond probablement à l'usage de la méthode PHP setFileUploadSupport (true) - indique à l'objet facebook
de coder le corps du message sous la forme multipart/form-data
avant de l'envoyer)
Malheureusement, le sous-problème '2' peut vous mordre - il n'y a aucun moyen (la dernière fois que j'ai regardé) d'extraire les octets d'une image à partir de l'objet Image fourni par le navigateur.
Si l'image à télécharger est accessible via une URL, vous pouvez récupérer les octets avec XmlHttpRequest. Pas mal.
Si l'image provient du bureau de l'utilisateur, votre recours probable est d'offrir à l'utilisateur un:
<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>
(notez que source
fait référence au nom donné au widget de téléchargement de fichier)
... et espère que FB a prévu de recevoir les données de cette manière (essayez-le d'abord avec un formulaire HTML statique avant de le coder de manière dynamique dans JS). On pourrait en déduire que ce serait le cas, puisqu'ils n'offrent pas un autre moyen de le faire.
Oui, c’est possible, je trouve 2 solutions pour faire cela et elles sont très similaires L’un pour l’autre, vous avez juste besoin de définir le paramètre url à l’image externe url
PREMIER en utilisant 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);
}
});
et SECOND one en utilisant jQuery Post request et 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");
}
});
j'ai utilisé le code @ Владимир Дворник avec quelques modifications, j'avais le même problème et avec ce code cela fonctionnait très bien:
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);
}
});
Les photos peuvent être téléchargées sur le profil facebook en utilisant Ajax comme suit.
$.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"); }
});
C’est donc le moyen le plus simple d’afficher une photo sur un profil Facebook avec l’API GRAPH.
Dans beaucoup de réponses j'ai vu que l'URL de l'image est shwon par la source, l'image ou l'image etc. mais cela ne fonctionne pas.
L'utilisation de source, image ou image conduit à un (# 324) Nécessite le téléchargement du fichier error.
Le meilleur moyen d'éviter l'erreur 324.
Seule la réponse de @ Thiago répond à la question de uploader des données via javascript. J'ai constaté que l'API Facebook JS ne couvre pas cette situation.
J'ai également préparé et testé ma solution personnelle.
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]
API de fichier HTML5 lue sous forme de texte et binaire
FormData
& File
, mais malheureusement, dans ce cas, il existe de nombreuses incompatibilités qui rendent le processus plus difficile à utiliser, et vous finissez par scotcher les conduits autour des incohérences - mon choix a donc été données manuelles Assemblage puisque les normes HTTP changent rarement :)jQuery.ajax
, jQuery.extend
, jQuery.each
Oui, vous pouvez faire cela en publiant des données sur un iframe comme ici , ou vous pouvez utiliser jQuery File Upload . Le problème est que vous ne pouvez pas obtenir de réponse de iframe, vous pouvez utiliser le plugin un handle de page.
Exemple: télécharger une vidéo à l'aide de jQuery File Upload
<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>
Pour télécharger un fichier à partir de l'ordinateur local avec Javascript, essayez 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>
Une démo de téléchargement est disponible sur http://adodson.com/hello.js/demos/upload.html
https://stackoverflow.com/a/16439233/68210 contient une solution qui fonctionne si vous devez télécharger les données photo elles-mêmes sans disposer d'une URL.
Cela marche:
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);
};
Cela fonctionne toujours. Je l'utilise comme ci-dessous:
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);
}
Je dois demander cependant si vos gens savent si cela est conseillé ou présente un risque important pour la sécurité par rapport à l'utilisation de PHP api pour Facebook.
Je semble avoir un problème similaire, mais les solutions ci-dessus n'ont pas fonctionné.
J'utilisais la solution suggérée par Arrabi (utilisez uniquement la propriété url) pour publier des images sans aucun problème. Mes images sont environ 2-3 MB chacun.
Lorsque j'ai migré mon application vers un autre serveur (en modifiant l'URL absolue de mes images dans l'article), la méthode ne cessait de me donner 324 erreurs pour des images d'une taille supérieure à 100 000 environ.
Je pensais que cela était dû à certains réglages d’Apache, mais lorsque j’ai changé d’Apache pour lighttpd, le problème était toujours là.
Les connexions de Facebook apparaissent dans mon journal (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: // développeurs .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) "
Seul test2.png a réussi.
J'utilise ce qui suit pour partager une photo (certains BitmapData du framework Phaser). Cela semble fonctionner ...
// 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);
}
Si quelqu'un cherche encore comment télécharger directement de la toile sur des photos Facebook, cela fonctionne pour moi:
function postImageToFacebook(token, imageData, message, successCallback, errorCallback) {
var fd = new FormData();
fd.append("access_token", token);
fd.append("source", imageData);
fd.append("caption", message);
$.ajax({
url: "https://graph.facebook.com/me/photos?access_token=" + token,
type: "POST",
data: fd,
processData: false,
contentType: false,
cache: false,
success: function (data) {
successCallback(data);
},
error: function (shr, status, data) {
errorCallback(data);
},
complete: function (data) {
console.log('Completed');
}
});
}
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/jpeg'});
}
Pour l'utiliser
// *IMPORTANT*
var FBLoginScope = 'publish_actions'; // or sth like 'user_photos,publish_actions' if you also use other scopes.
var caption = "Hello Facebook!";
var successCallback = ...;
var errorCallback = ...;
var data = $('#your_canvas_id')[0].toDataURL("image/jpeg");
try {
imageData = dataURItoBlob(data);
} catch (e) {
console.log(e);
}
FB.getLoginStatus(function (response) {
if (response.status === "connected") {
postImageToFacebook(response.authResponse.accessToken, imageData, caption, successCallback, errorCallback);
} else if (response.status === "not_authorized") {
FB.login(function (response) {
postImageToFacebook(response.authResponse.accessToken, imageData, caption, successCallback, errorCallback);
}, {scope: FBLoginScope});
} else {
FB.login(function (response) {
postImageToFacebook(response.authResponse.accessToken, imageData, caption, successCallback, errorCallback);
}, {scope: FBLoginScope});
}
});
Modifié depuis: http://gorigins.com/posting-a-canvas-image-to-facebook-and-Twitter/