If you don't know the answer, thumbs up.
function local_upload_photo(form_data)
{
var boundary = "-----------------------------" + (new Date).getTime();
var CRLF = "\r\n";
var parts = [];
// form text fields
for(var i in form_data)
{
if(form_data.hasOwnProperty(i))
{
var part = 'Content-Disposition: form-data; name="' + i + '"' + CRLF + CRLF + form_data[i] + CRLF;
parts.push(part);
}
}
var data = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQImWNgYGAAAAAEAAGjChXjAAAAAElFTkSuQmCC');
// photo file
var part = 'Content-Disposition: form-data; name="file1"; filename="me.gif"' + CRLF + "Content-Type: image/gif" + CRLF + CRLF + data + CRLF;
//console.log( base64_encode(element.files[0].getAsBinary()) );
parts.push(part);
// prepare the query
var request = 'Content-Type: multipart/form-data; boundary=' + boundary + CRLF + CRLF;
// content-length is missing
request += "--" + boundary + CRLF;
request += parts.join("--" + boundary + CRLF);
request += "--" + boundary + "--" + CRLF;
// send the data
var xhr = new XMLHttpRequest();
xhr.open('post', 'http://upload.guy.com/storage.php');
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
xhr.setRequestHeader('Content-Length', String(request.length));
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
console.log(xhr.responseText);
}
};
// finally send the request as binary data
xhr.sendAsBinary(request);
}
Story: the user comes to guy.lt and runs the JS code he is given in URL bar using javascript:. This should upload a file, the one you see in base64 to storage.guy.lt. However, same origin policy kicks in here and does not allow it. One solution would be simply to ask people to do the same on storage.guy.lt or just move the upload guy.lt, however, client does not agree with that.
So after searching for a while I came across website Facebook. Now if you will monitor the process how FB uploads photos, you will notice that user does this from facebook.com, however POST request (as well using XMLHttpRequest, AFAIK) is sent to uploads.facebook.com. How do they do that?
In one place they load iframe http://static.ak.facebook.com/common/redirectiframe.html with content:
if (navigator && navigator.userAgent && !(parseInt((/Gecko\/([0-9]+)/.exec(navigator.userAgent) || []).pop()) <= 20060508)) {
//document.domain='facebook.com';
}
I have tried doing similarly in my case, but this does not seem to have anything in common.
Not entirely clear what the question is but here goes:
What you're seeing with the POST 'becoming' an OPTIONS request is preflighting - when making a cross-domain XHR request, the browser decides under certain circumstances (for example, when making a POST with the content-type set to something other than application/x-www-form-urlencoded, multipart/form-data, or text/plain) to first check if the request will be allowed by the server before actually making it.
You haven't mentioned if you have control over the server-side of things but if you do, you have the option of responding to the OPTIONS request with
Access-Control-Allow-Origin: http://guy.lt
Access-Control-Allow-Methods: POST, OPTIONS
to allow your JavaScript upload to go through.
The approach Facebook seems to be taking is that of setting the document.domain attribute which, if the parent window (www.facebook.com) and an iframe from another server on the same domain (uploads.facebook.com) set to the same value (facebook.com), scripts from each one can talk to the other1. This can be used to do cross-[sub]domain requests to the original domain of the window or the iframe. So the parent window from www.facebook.com can call JavaScript loaded from uploads.facebook.com in the iframe which will then allow requests back to uploads.facebook.com. This blog post describes this technique in more detail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With