问题
I am using the v2.0 version of the facebook graph api and I am trying to upload a picture to v2.0/me/photos, but unfortunately I get this error (#324) Requires upload file
, which is strange, because I have publish_actions permission and the documentation says this is all I need.
I am using phonegap, therefore the normal JS SDK doesn't work for me and the cordova-facebook-plugin makes cordova to fail it's build (followed instructions on at least 5 forums/blogs, nothing worked), that's why I am using pure XMLHTTPRequests and AJAX requests for my application. Everything works fine (I can post a message to user's wall, log in just fine), except for this image upload. This is the function I am using (data is URI of an image):
function postImage(data, message) {
var imageData = data.replace('data:image/jpeg;base64,', ''),
mimeType = 'image/jpg',
authToken = tokenStore['acess.token'],
filename = 'bikeDice_screenshot_' + Math.round((+(new Date()) + Math.random())),
deferred = $q.defer();
try {
var blob = dataURItoBlob(imageData, mimeType);
} catch (e) {
alert(e);
}
var fd = new FormData();
fd.append("access_token", authToken);
fd.append("source", '%7B' + blob + '%7D');
fd.append("message", message);
fd.append("no_story", false);
try {
$.ajax({
url: 'https://graph.facebook.com/v2.0/me/permissions?access_token=' + authToken,
type: 'GET',
success: function (data) {
alert(JSON.stringify(data));
},
error: function (err) {
alert(err);
}
});
$.ajax({
url: "https://graph.facebook.com/v2.0/me/photos?access_token=" + authToken,
type: "POST",
data: fd,
processData: false,
contentType: false,
cache: false,
success: function (data) {
console.log("success " + data);
deferred.resolve(data);
},
error: function (shr, status, data) {
alert(JSON.stringify(shr));
deferred.reject(data);
},
complete: function () {
console.log("Ajax Complete");
}
});
} catch (e) {
alert('error in ajax request ');
alert(JSON.stringify(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
try {
var blob = new Blob([ia], {
type: mime
});
} catch (e) {
try {
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
if (e.name == 'TypeError' && window.BlobBuilder) {
var bb = new BlobBuilder();
bb.append([ia.buffer]);
var blob = bb.getBlob(mime);
var bb = new BlobBuilder();
} else if (e.name == "InvalidStateError") {
// InvalidStateError (tested on FF13 WinXP)
var blob = new Blob([ia.buffer], {
type: mime
});
} else {
alert('Blob constructor unsupported entirely! ');
}
} catch (e) {
alert(e);
}
}
return blob;
}
return deferred.promise
};
P.S.: On smartphone, the script always goes to this if in the try/catch block:
if (e.name == 'TypeError' && window.BlobBuilder) {
var bb = new BlobBuilder();
bb.append([ia.buffer]);
var blob = bb.getBlob(mime);
var bb = new BlobBuilder();
}
P.S.2: I tried adding &upload_file=true
to the url of the post request, no luck really... ;/
回答1:
This is the solution I found, using the cordova file-transfer plugin, works like a charm with data URI:
function postImage(fileURI, message) {
var deferred = $q.defer();
var win = function (r) {
deferred.resolve(r);
}
var fail = function (error) {
deferred.reject(error);
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = 'name_of_photo_' + Math.round((+(new Date()) + Math.random()));
options.mimeType = "image/jpg";
var params = new Object();
params.access_token = "your facebook access token ;)";
params.message = message;
params.no_story = false;
options.params = params;
var ft = new FileTransfer();
ft.upload(fileURI, "https://graph.facebook.com/v2.0/me/photos", win, fail, options);
return deferred.promise;
}
But first, add the plugin to cordova, using cordova plugin add org.apache.cordova.file-transfer
来源:https://stackoverflow.com/questions/25232497/phonegap-cordova-upload-photo-to-graph-facebook-requires-upload-file