如果您不知道答案,请竖起大拇指。
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);
}
故事:用户来guy.lt
并使用javascript:
运行他在URL栏中给出的JS代码。这应该上传一个文件,即您在base64
中看到storage.guy.lt
的文件。但是,同样的原始政策在这里开始并且不允许它。一个解决方案就是让人们在storage.guy.lt上做同样的事情,或者只是移动上传guy.lt,但客户不同意。
所以在搜索了一段时间后我遇到了Facebook网站。现在,如果您要监控FB上传照片的过程,您会注意到用户从facebook.com执行此操作,但POST请求(以及使用XMLHttpRequest,AFAIK)也会发送到uploads.facebook.com。他们是如何做到的?
在一个地方,他们加载了包含内容的iframe http://static.ak.facebook.com/common/redirectiframe.html
:
if (navigator && navigator.userAgent && !(parseInt((/Gecko\/([0-9]+)/.exec(navigator.userAgent) || []).pop()) <= 20060508)) {
//document.domain='facebook.com';
}
我在我的案例中尝试过类似的做法,但这似乎没有任何共同之处。
答案 0 :(得分:2)
不完全清楚问题是什么,但这里是:
您在POST'成为'OPTIONS请求时所看到的是preflighting
- 在发出跨域XHR请求时,浏览器会在某些情况下决定(例如,在发布POST时)将content-type设置为application/x-www-form-urlencoded, multipart/form-data, or text/plain
以外的其他内容,首先检查服务器在实际生成之前是否允许该请求。
您没有提及是否可以控制服务器端的事情,但如果您这样做,则可以选择使用
响应OPTIONS
请求
Access-Control-Allow-Origin: http://guy.lt
Access-Control-Allow-Methods: POST, OPTIONS
允许您上传JavaScript代码。
Facebook似乎采用的方法是设置document.domain
属性,如果父窗口(www.facebook.com)和来自同一域上其他服务器的iframe(上传。 facebook.com)设置为相同的值(facebook.com),每个人的脚本可以与另一个 1 交谈。这可用于对窗口的原始域或iframe执行跨[子]域请求。因此,来自www.facebook.com的父窗口可以调用从iframe中的uploads.facebook.com加载的JavaScript,然后允许请求返回uploads.facebook.com。 This blog post更详细地描述了这种技术。