Mixed Content Error (Http/Https) - javascript

I have mixed content error, on web site used both http and https protocols.
Here's the error from Chrome console:
Mixed Content: The page at 'https://www.amazon.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://www.amazon.com/../?redirect=true'. This request has been blocked; the content must be served over HTTPS.
Here's screenshot with the error: http://prntscr.com/9os5li
Was found some solution like:
Change link from "http://" to "https://" in
Blocked loading mixed active content.
Nothing helped me, because Amazon server drop it all the time when I change link in code or manual from http to https drop it and make it as http.
For example this one Link 2 I can't use here https, because of this I have mixed content error.
Here's my AJAX where I make a call:
$.ajax({
url: "//" + MWS_URL + rest_path,
data: request,
dataType: 'text',
type: 'POST',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
beforeSend: function(req) {
//req.setRequestHeader("User-Agent", "chrome extension");
req.setRequestHeader("x-amazon-user-agent", "chrome extension");
},
success: function(data){
if (onSuccess) {
onSuccess(data);
}
},
error: function(jqXHR, textStatus, errorThrown) {
if (onError) {
onError(jqXHR, textStatus);
}
}
});
setTimeout(callService, 1000);
}
Request:
requests.push(
$.get(link.URL, function (data) {
if (IsCancel()) {
return;
}
var jdata = $($.parseHTML(data));
var parser = new ProductPageParser(jdata, link.URL);
if (!parser.isValidProduct()) {
console.log(link.URL + " is not a valid product, skipped.");
link.processed = true;
return;
}
// Process associated (linked) product on this page according to user preferences.
crawlLinkedProducts(jdata, link.URL, config);
// Store product into a collection.
var product = getProductForParser(parser, link);
//product.dbRawProductURL = urlRaw;
if (product) {
products.push(product);
}
link.processed = true;
})
);
And as I have parse in parser, here's second level parser. I parsed products on main page:
$(productUrls).each(function (index, link) {
if (!link.processed) {
console.log("Download second level -> " + link.URL);
requests_2level.push(
$.post(link.URL, "", function (data) {
if (IsCancel()) {
return;
}
console.log("End download second level -> " + link.URL);
var jdata = $($.parseHTML(data));
var parser = new ProductPageParser(jdata, link.URL);
if (!parser.isValidProduct()) {
console.log(link.URL + " is not a valid product, skipped.");
link.processed = true;
return;
}
var hackUrl = "//amazon.com/o/ASIN/" + parser.getAsin();
link.URL = hackUrl;
var product = getProductForParser(parser, link);
if (product) {
products.push(product);
}
link.processed = true;
})
);
}
});
Anyone have idea how to fix this problem?

If Amazon keep redirecting you from HTTPS to HTTP then there is nothing you can do about that short of:
Complaining hard enough at Amazon that they fix it or
Using a difference service

Decide whether to use http or https and use the same on for every call.

Related

Is there a way to make an ajax call to a specific IP by URL?

I am writing a script that does a lookup for a domain, then will iterate through each IP for reachability.
For instance, if you look up google.com, there are 6 IPs. I want to go to google.com, but force it to use each IP, returning 6 different results.
I have everything, except how do I use the IP? If I just specify the IP, it fails as the servers don't respond to the IP - site is bound to the domain.
I am using npm & electron if that helps...
function checkConnection(myIP, myPort, myDomain) {
var isAccessible = null;
var url = "https://" + myDomain + ":" + myPort;
console.log(myDomain + " check at "+ url);
$.ajax({
url: url,
type: "get",
cache: false,
dataType: 'text',
timeout : 1500,
complete : function(xhr, responseText, thrownError) {
if(xhr.status != "404") {
isAccessible = true;
console.log(myDomain + " check at "+ url + " passed");
console.log(xhr);
return true;
}
else {
isAccessible = false;
console.log(myDomain + " check at "+ url + " failed");
console.log(xhr);
return false;
}
}
});
}

jQuery sends OPTIONS instead of POST request to REST on localhost

I am trying to send a form thru POST to my REST Resource (Java) and I am not able to, as my request gets sent as OPTIONS instead. I Know that the REST Resource is fine since it works perfectly while I test it with Poster Firefox.
jQuery/Ajax call:
function loadTwitter(){
arrayTweets = new Array();
var urlTwitter = "http://localhost:8081/streamingvideoservice/services/twitter/retrieveTweets";
$.ajax({
type: "POST",
url: urlTwitter,
contentType: "application/x-www-form-urlencoded",
//accept: "application/json",
data: $("form#mapForm").serialize(),
dataType: "json",
async: false,
success: function (resp, status, xhr) {
$("#message").html("STATUS: " + xhr.status + " " + xhr.statusText + "\n" + resp);
$("#message").hide();
$.each(resp, function() {
$.each(this, function(i, item) {
arrayTweets.push(item);
});
});
displayTweets();
},
error: function(resp, status, xhr){
$("#message").html("ERROR: " + xhr.status + " " + xhr.statusText + "\n" + resp.e);
$("#message").show();
}
});
}
REST Resource:
#POST
#Path("/retrieveTweets")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces("application/json")
public List<Tweet> retrieve(#FormParam("lat") Double Latitude, #FormParam("lon") Double Longitude, #FormParam("rad") Integer Radius, #FormParam("from") String From, #FormParam("to") String To) {
ArrayList<Tweet> lTweets = new ArrayList<Tweet>();
boolean status = false;
Twitter twitter = new TwitterFactory().getInstance();
AccessToken accessToken = new AccessToken(TwitterInterface.ACCESS_TOKEN, TwitterInterface.ACCESS_TOKEN_SECRET);
twitter.setOAuthConsumer(TwitterInterface.CONSUMER_KEY, TwitterInterface.CONSUMER_SECRET);
twitter.setOAuthAccessToken(accessToken);
try {
Query query = new Query("");
GeoLocation geo = new GeoLocation(Latitude, Longitude);
query.setGeoCode(geo, Radius, Query.KILOMETERS);
query.setCount(100);
query.setSince(From);
query.setUntil(To);
QueryResult result;
result = twitter.search(query);
List<Status> tweets = result.getTweets();
for (Status tweet : tweets) {
System.out.println("#" + tweet.getUser().getScreenName() + " - " + tweet.getText() + " - " + tweet.getCreatedAt());
Tweet t = new Tweet();
t.setUser(tweet.getUser().getScreenName());
t.setText(tweet.getText());
lTweets.add(t);
}
}
catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to search tweets: " + te.getMessage());
System.exit(-1);
}
return lTweets;
}
I am using jQuery 1.9.1 and hosting the Resource on Tomcat 6.
Any help is appreciated.
Thanks in advance.
You appear to be making a cross origin Ajax request. This requires that the server provides an Access-Control-Allow-Origin header to grant permission to the site hosting the page containing the JS to read the data.
Something about the request (probably the X-Requested-With header that jQuery adds to Ajax requests) is triggering a preflight request which uses an OPTIONS request to ask the server for permission before making the main request.
You will need to configure the server to provide an OPTIONS response with suitable Access Control headers as per the CORS specification (linked above).
Solved it with a GET instead and passing the parameters in the URI.

Sending Data From background.js to extension.js in crossrider

I am developing a browser extension using crossrider.
I have added a context menu (background.js)
var ContextData;
appAPI.contextMenu.add("key1", "Send Data To Server", function (data) {
var ContextData = 'pageUrl: ' + data.pageUrl + '\r\n' +
'linkUrl: ' + data.linkUrl + '\r\n' +
'selectedText:' + data.selectedText + '\r\n' +
'srcUrl:' + data.srcUrl;
}, ["all"]);
On user click I want to send ContextData to extension.js. At extension.js some function will receive the data and send it to my server (A Rest API which will accept the data).
To send data to the server I have tested this and it works fine (code sample in extension.js)
appAPI.ready(function($) {
var dataToSend =="test data";
appAPI.request.post({
url: 'REST API URL',
postData: dataToSend,
onSuccess: function(response, additionalInfo) {
var details = {};
details.response = response;
},
onFailure: function(httpCode) {
// alert('POST:: Request failed. HTTP Code: ' + httpCode);
}
});
});
How can I write a function to accept ContextData from background.js and assign it to dataToSend in extension.js?
#Neel If I understand your requirements correctly, #Rob is essentially correct though a little clarification may help
By design/architecture, the extension.js code runs on each HTML page i.e. a separate extension.js instance is run for each URL that loads. In contrast, the context menu runs at the browser level (not HTML page) and is hence correctly coded in background.js file. However, the background.js code does not have direct access to the extension.js instance code running on the HTML page in the active tab and must therefore communicate the data via messaging. (For more information about scopes, see Scopes Overview)
Obviously, a user clicks the context menu item on the active tab (i.e. the page showing the HTML page being viewed); hence, once the ContextData string is created, you can use appAPI.message.toActiveTab to send the string to the extension.js instance running on the page/tab where the the context menu item was clicked.
This being the case, using your code example you can achieve this goal as follows:
background.js:
appAPI.ready(function($) {
var ContextData;
appAPI.contextMenu.add("key1", "Send Data To Server", function (data) {
var ContextData = 'pageUrl: ' + data.pageUrl + '\r\n' +
'linkUrl: ' + data.linkUrl + '\r\n' +
'selectedText:' + data.selectedText + '\r\n' +
'srcUrl:' + data.srcUrl;
appAPI.message.toActiveTab({type:'dataToSend', data: ContextData});
}, ["all"]);
});
extension.js:
appAPI.ready(function($) {
var dataToSend =="test data";
appAPI.message.addListener(function(msg) {
if (msg.type === 'dataToSend') {
appAPI.request.post({
url: 'REST API URL',
postData: dataToSend,
onSuccess: function(response, additionalInfo) {
var details = {};
details.response = response;
},
onFailure: function(httpCode) {
// alert('POST:: Request failed. HTTP Code: ' + httpCode);
}
});
}
});
});
[Disclaimer: I am a Crossrider employee]

extjs 4.1 download xml file using ajax

i want to download a file using extjs 4.1.
The file name is "wsnDataModel.xml".
I've tryed with all things suggested in other posts:
//function invoked clicking a button
DwDataModel : function(th, h, items) {
//direct method that build in file in the location calculated below with "certurl" (I've verified)
Utility.GetDataModel(function(e, z, x) {
if (z.message) {
//the server method should give an error message
Ext.create('AM.view.notification.toast', {
title : 'Error',
html : z.message,
isError : true
}).show();
} else {
// navigate to get data
var certurl = 'http://' + window.location.host
+ '/AdminConsole3/' + e;
Ext.Ajax.request({
method : 'GET',
url : 'http://' + window.location.host
+ '/AdminConsole3/' + e,
success : function(response, opts) {
//the following navigate and openthe file in the current browser page.
//I don't want to change the current browser page
//window.location.href = certurl;
//the same behaviour with
//document.location = certurl;
//and this don't work at all
window.open(certurl,'download');
},
failure : function(response, opts) {
console
.log('server-side failure with status code '
+ response.status);
console.log('tried to fetch ' + url);
}
}, this, [certurl]);
}
}, th);
}
the "navigation" redirect the application (i don't want to redirect the application) like this:
and I'would like to download the file like this image:
I think it's very simple. How to do that?
thank you
Very simple: this is the success function.
success: function (response, opts) {
var link = document.createElement("a");
//this gives the name "wsnDataModel.xml"
var fileName = certurl.substring(certurl.lastIndexOf('/') + 1);
link.download = fileName;
link.href = certurl;
link.click();
}

Facebook Graph API - upload photo using JavaScript

Is it possible to upload a file using the Facebook Graph API using javascript, I feel like I'm close. I'm using the following 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!');
}
});
}
Upon running this I receive the following error...
"OAuthException" - "(#324) Requires upload file"
When I try and research this method all I can find out about is a php method that apears to solve this
$facebook->setFileUploadSupport(true);
However, I am using JavaScript, it looks like this method might be to do with Facebook Graph permissions, but I already have set the permissions user_photos and publish_stream, which I believed are the only ones I should need to perform this operation.
I have seen a couple of unanswered questions regarding this on stackoverflow, hopefully I can explained myself enough. Thanks guys.
Yes, this is possible, i find 2 solutions how to do that and they are very similar
to each other, u need just define url parameter to external image url
FIRST one using 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);
}
});
and SECOND one using jQuery Post request and 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");
}
});
EDIT: this answer is (now) largely irrelevant. If your image is on the web, just specify the url param as per the API (and see examples in other answers). If you would like to POST the image content to facebook directly, you may want to read this answer to gain understanding. Also see HTML5's Canvas.toDataUrl().
The API says: "To publish a photo, issue a POST request with the photo file attachment as multipart/form-data."
FB is expecting that the bytes of the image to be uploaded are in the body of the HTTP request, but they're not there. Or to look at it another way - where in the FB.api() call are you supplying the actual contents of the image itself?
The FB.api() API is poorly documented, and doesn't supply an example of an HTTP POST which includes a body. One might infer from the absence of such an example that it doesn't support this.
That's probably OK - FB.api() is using something called XmlHttpRequest under the covers which does support including a body ... look it up in your favourite JavaScript reference.
However, you'll still have 2 sub-problems to solve:
how to prepare the image bytes (and rest of the request) as multipart/form-data; and
getting the bytes of the image itself
(incidentally, the need to encode the message body is probably what the PHP setFileUploadSupport(true) method is for - tell the facebook object to encode the message body as multipart/form-data before sending)
But it's a bit meessier than that
Unfortunately, sub-problem '2' may bite you - there is no way (last time I looked) to extract the bytes of an image from the browser-supplied Image object.
If the image to be uploaded is accessible via a URL, you could fetch the bytes with XmlHttpRequest. Not too bad.
If the image is coming from the user's desktop, your probable recourse is to offer the user a:
<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>
(notice that source references the name given to the file-upload widget)
... and hope that FB anticipated receiving the data in this manner (try it with a static HTML form first, before coding it up dynamically in JS). One might infer that in fact it would, since they don't offer another means of doing it.
i used #Владимир Дворник code with some modification, I had the same issue and with this code it worked very well:
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);
}
});
Photos can be uploaded to facebook profile using Ajax as follows.
$.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"); }
});
So this is the best way to post photo to a facebook profile with GRAPH API and is the simple one.
In many answer i have seen that image url is shwon by the source,picture or image etc but that doesn't works.
The use of of source,picture or image leads to a (#324) Requires upload file error .
Best way to avoid the 324 error.
Only #Thiago's answer is answering the question of uploading data via javascript. I've found that the Facebook JS API doesn't cover this situation.
I've also brew & tested my personl solution.
Main steps
Get the binary data of the image (I've used a canvas, but using an input box is possible as well)
Form a multipart request with all necesarry data for the graph API call
Include the binary data in the request
Encode everything in a binary array and send it so via XHR
Code
Conversion utilities
var conversions = {
stringToBinaryArray: function(string) {
return Array.prototype.map.call(string, function(c) {
return c.charCodeAt(0) & 0xff;
});
},
base64ToString: function(b64String) {
return atob(b64String);
}
};
Image posting snippet
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);
};
Usage
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
}
});
Extra
Extracting the binary string representation of a canvas image
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);
}
Information on how to load the binaryString from an input[type=file]
HTML5 File API read as text and binary
Notes:
There are of course alternative approaches as well
Using an HTML form in an iframe - you cannot get the response from the call
Using a FormData & File approach, but unfortunately in this case there are a lot of incompatilities which make the process harder to use, and you would end up duct-taping around the inconsistencies - thus my choice was manual data assembly since HTTP standards rarely change :)
The solution does not require any special HTML5 features.
The above example uses jQuery.ajax, jQuery.extend, jQuery.each
Yes, you can do this posting data to an iframe like here, or you can use jQuery File Upload .
The problem is you can't get response from iframe, using plugin you can use a page handle.
Example: upload a video using 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>
To upload a file from the local computer with just Javascript try 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>
There's an upload demo at http://adodson.com/hello.js/demos/upload.html
https://stackoverflow.com/a/16439233/68210 contains a solution that works if you need to upload the photo data itself and don't have a url.
This still works. I am using it as below:
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);
}
I have to ask though if you people have any idea if this is advisable or has a big security risk compared to using PHP api for Facebook.
This works:
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);
};
I seem to have a similar problem, but solutions above didn't work.
I was using the solution suggested by Arrabi (just use the url property only) to post images without any problem. My images are around 2-3 MB each.
When I migrated my app to another server (changing the absolute url of my images in the post) the method kept giving me 324 errors for images above around 100k size.
I thought it was due to some Apache setting on my end, but when I changed apache for lighttpd the problem was still there.
The connections from Facebook actually show up in my (apache) log:
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://developers.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)"
Only test2.png succeeded.
I use the following to share a photo (some BitmapData from the Phaser framework). It seems to work...
// 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);
}
In case anyone still looking for how to upload directly from canvas to Facebook photos, this works for me:
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'});
}
To use it
// *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});
}
});
Modified from: http://gorigins.com/posting-a-canvas-image-to-facebook-and-twitter/

Categories