setRequestHeader Content-Type导致POST请求成为OPTIONS [英] setRequestHeader Content-Type causes POST request to become OPTIONS

查看:576
本文介绍了setRequestHeader Content-Type导致POST请求成为OPTIONS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您不知道答案,请竖起大拇指。

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);
}

故事:用户来到 guy.lt ,并使用 javascript:运行在URL栏中给出的JS代码。这应该会将您在 base64 中看到的文件上传到 storage.guy.lt 。不过,同样的起源政策也在这里开始,不允许这样做。一个解决方案只是要求人们在storage.guy.lt上做同样的事情,或者只是移动上传的man.lt,但客户不同意。

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.

搜索一段时间后,我遇到了Facebook的网站。现在,如果您将监视FB上传照片的过程,您将注意到用户在facebook.com上执行此操作,但是POST请求(以及使用XMLHttpRequest,AFAIK)也被发送到uploads.facebook.com。他们如何做?

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?

在一个地方,他们加载iframe http://static.ak.facebook.com/common/redirectiframe.html 包含内容:

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:


  1. 您看到的成为OPTIONS请求的内容是 prelighting - 在进行跨域XHR请求时,浏览器在某些情况下决定(例如,在使用POST时,内容类型设置为除 application / x-www-form-urlencoded,multipart / form-data或text / plain 之外的其他内容),以首先检查请求是否在实际制作之前,服务器允许它。

  1. 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.

你没有提到是否可以控制服务器端的东西,但如果你这样做可以选择回应 OPTIONS 要求t与

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

允许您的JavaScript上传。

to allow your JavaScript upload to go through.

Facebook似乎正在采取的方法是设置 document.domain 属性,如果父窗口(www。 facebook.com)和另一台服务器上的iframe(uploads.facebook.com)设置为相同的值(facebook.com),每个脚本可以与另一个 1 。这可以用来对窗口或iframe的原始域进行跨[sub]域请求。所以从www.facebook.com的父窗口可以调用从uploads.facebook.com在iframe中加载的JavaScript,然后允许请求返回uploads.facebook.com。 这篇博文更详细地描述了这种技术。

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.

这篇关于setRequestHeader Content-Type导致POST请求成为OPTIONS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆