javascript 使用 jQuery 实现跨域文件上传

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28365417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 08:51:47  来源:igfitidea点击:

Cross domain file upload with jQuery

javascriptjqueryajaxcross-domain

提问by Sandip Karanjekar

My code is working fine for same domain.
But when I try it on cross domain with dataType: 'jsonp'& crossDomain: true
Code sample -

我的代码在同一个域中工作正常。
但是当我在跨域上尝试使用 dataType: 'jsonp'& crossDomain: true
代码示例时 -

var fa = new FormData();

fa.append("upload_pass", document.getElementById("upload_pass").files['0']);

$.ajax({    
    url: 'http://xxx.xx.xx.xx/upload.php',
    data: fa,
    contentType: false,
    processData: false,
    dataType: 'jsonp',
    crossDomain: true,
    type: 'GET',
    success: function(data) {
        alert(data);
    }
});

Is there any conceptual understanding gap or coding problem.
Please suggest.

是否有任何概念理解差距或编码问题。
请建议。

回答by JerryCauser

No way to upload file via GET. Even if you will use JSONP. JSONP is working just with GET requests. And you can't upload files with GET request (usually files upload with POST requests).

无法通过 GET 上传文件。即使您将使用 JSONP。JSONP 仅适用于 GET 请求。并且您不能使用 GET 请求上传文件(通常使用 POST 请求上传文件)。

If you wanna send cross domain POST request to some server, then you should be sure in next case:

如果您想向某个服务器发送跨域 POST 请求,那么您应该确定在下一种情况下:

That server should send you header Access-Control-Allow-Origin : *. Also you will may be need Access-Control-Allow-Methods: POSTheader.

该服务器应该向您发送 header Access-Control-Allow-Origin : *。你也可能需要Access-Control-Allow-Methods: POST标题。

If it has those headers, then you are lucky and you can POST your data on this server.

如果它有这些标题,那么你很幸运,你可以在这个服务器上发布你的数据。

P.S. You can try to use other methods to make valid cross domain request. Nice js library easyXDMfor cross domain requests, witch uses different ways to do it.

PS 您可以尝试使用其他方法进行有效的跨域请求。用于跨域请求的不错的js 库 easyXDM,女巫使用不同的方法来做到这一点。

回答by Arkantos

JSONP and CORS are two different things altogether.

JSONP 和 CORS 完全是两种不同的东西。

JSONP

JSONP

JSON with Padding is merely a hack taking advantage of the fact that there's no same origin policy restriction when downloading javascript files. As you can download only scripts, we make use of built-in data format JSON instead of XML or HTML. Also you can make only GET requests with JSONP because all it does is create a scriptwith srcset to some other domain and append it to your DOM, once it's downloaded, it is executed and that is when our callback is used to call code from original domain passing JSON object.

带有 Padding 的 JSON 只是一种利用下载 javascript 文件时没有同源策略限制这一事实的技巧。由于您只能下载脚本,因此我们使用内置数据格式 JSON 而不是 XML 或 HTML。此外,您只能使用 JSONP 发出 GET 请求,因为它所做的只是为其他域创建一个scriptwith srcset 并将其附加到您的 DOM,一旦下载,就会执行它,这就是我们的回调用于从原始域调用代码的时候传递 JSON 对象。

CORS

CORS

Cross-origin resource sharing is a standard from W3C that allows many resources (e.g. fonts, JavaScript, etc.) on a web page to be requested from another domain. You're not limited to using just GET, you can use all the usual HTTP methods like POST, HEAD, PUT , DELETE and others

跨域资源共享是 W3C 的一项标准,它允许从另一个域请求网页上的许多资源(例如字体、JavaScript 等)。您不仅可以使用 GET,还可以使用所有常用的 HTTP 方法,如 POST、HEAD、PUT、DELETE 等

How can you make a CORS request :

您如何提出 CORS 请求:

It's as simple as changing the url in your AJAX call to some other domain, that's it no other changes from client side.

就像将 AJAX 调用中的 url 更改为其他域一样简单,客户端没有其他更改。

If your browser supports CORS, then based on the type of request (simple/complex), a pre-flight OPTIONS request might be fired to get information about what type of methods & content-types are allowed for this domain and this OPTIONS response will be cached.

如果您的浏览器支持 CORS,则根据请求的类型(简单/复杂),可能会触发飞行前 OPTIONS 请求以获取有关此域允许的方法类型和内容类型的信息,并且此 OPTIONS 响应将被缓存。

Going forward, whenever you make an AJAX call to some other domain, Behind the scenes, browser sends an Originrequest header. For example, if a page from google makes an AJAX call to facebook, something like this is added to request headers

展望未来,每当您对其他域进行 AJAX 调用时,在幕后,浏览器都会发送Origin请求标头。例如,如果来自 google 的页面对 facebook 进行了 AJAX 调用,则会将类似的内容添加到请求标头中

Origin: http://google.com

When facebook sees this header, it will check if google.com is in their valid list of allowed hosts and agrees for this by sending the following headers in response.

当 facebook 看到这个标头时,它会检查 google.com 是否在他们允许的主机的有效列表中,并通过发送以下标头作为响应来同意这一点。

Access-Control-Allow-Origin: http://google.com

Note that the host name in Originand Allow-Originheaders should match for the browser to accept and act on the response received. You can even restrict the methods & custom headers allowed by setting the following headers in response

请注意,OriginAllow-Origin标头中的主机名应该匹配,浏览器才能接受并根据收到的响应采取行动。您甚至可以通过在响应中设置以下标头来限制允许的方法和自定义标头

Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER

Finally to answer your question, change your Ajax definition like below

最后回答你的问题,改变你的 Ajax 定义,如下所示

$.ajax({    
    url: 'http://some-other-domain.com/upload.php',
    data: fa,
    contentType: false,
    processData: false,
    type: 'POST',
    success: function(data) {
        alert(data);
    }
});

As you're just doing a simple POST call with file, its a simple request so Allow-Origin header will suffice. In your PHP, read the Originheader check if it's in your list and set the same header value in Allow-Origin response header. I'm not aware of PHP but it's hopefully something like this :)

由于您只是对文件进行简单的 POST 调用,因此它是一个简单的请求,因此 Allow-Origin 标头就足够了。在您的 PHP 中,阅读Origin标头检查它是否在您的列表中,并在 Allow-Origin 响应标头中设置相同的标头值。我不知道 PHP 但它希望是这样的 :)

<?php
$headers = apache_request_headers();

  foreach ($headers as $header => $value) {
     if($header == "Origin"){
        /* check if $value is in your list
         if yes, set the response header */
         header('Access-Control-Allow-Origin: $value');
         /* adding just this header will allow any method from this 
            domain, in case you need to allow only POST method add
            Access-Control-Allow-Methods header as well */
         break;
      }
  }
  // do the remaining processing of request
?>

More resources on

更多资源

Hope this answers your question :)

希望这能回答你的问题:)

回答by Quentin

You can't make any type of request using JSONP other than GET. You can't upload a file using a GET request (unless it is a very small file that you can read with JavaScript and convert to a string that can be treated as regular form data).

除了 GET,您不能使用 JSONP 发出任何类型的请求。您不能使用 GET 请求上传文件(除非它是一个非常小的文件,您可以使用 JavaScript 读取并转换为可以被视为常规表单数据的字符串)。

You need to switch to using POST with CORS (or a proxy on the same origin) to disable the same origin policy.

您需要切换到将 POST 与 CORS(或同一来源的代理)一起使用以禁用同源策略。

回答by Pankaj Bisht

For cross domain work you need these things -

对于跨域工作,您需要这些东西-

1 :- You need permission of server. Like Access-Control-Allow-Origin : *.

1 :- 您需要服务器的许可。像 Access-Control-Allow-Origin : *.

2 :- If you are using jquery then you can use jsonp method.

2 :- 如果您使用的是 jquery,那么您可以使用 jsonp 方法。

3 :- If you wants to work with plain javascript then you can use this link -

3 :- 如果你想使用普通的 javascript 那么你可以使用这个链接 -

How to make a JSONP request from Javascript without JQuery?

如何在没有 JQuery 的情况下从 Javascript 发出 JSONP 请求?

回答by scgough


As people have said - GET is not the way to do this. I've seen this kind of thing done with via a hidden iFrame. You can probably find various jQuery plugins to achieve the desired result but there's one I've found called "jQuery iFrame Transport"
https://cmlenz.github.io/jquery-iframe-transport/
Hopefully that will help you.


正如人们所说 - GET 不是这样做的方法。我已经看到通过隐藏的 iFrame 完成这种事情。您可能会找到各种 jQuery 插件来实现所需的结果,但我找到了一个名为“jQuery iFrame Transport”的插件
https://cmlenz.github.io/jquery-iframe-transport/
希望对您有所帮助。

回答by Akshat

You cannot upload file using JSONP or using GET request. Are you sure that it was working for the same origin earlier?

您不能使用 JSONP 或使用 GET 请求上传文件。你确定它早些时候为同一个来源工作吗?

You have to send a cross-domain XHR request to upload file. You can use JQuery File upload for this. https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads

您必须发送跨域 XHR 请求才能上传文件。您可以为此使用 JQuery 文件上传。 https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads