使用 jQuery 进行跨域文件上传
Cross domain file upload with jQuery
我的代码在同一域中工作正常。
但是当我使用 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);
}
});
是否存在概念理解差距或编码问题。
请提出建议。
除了 GET,您不能使用 JSONP 发出任何类型的请求。您不能使用 GET 请求上传文件(除非它是一个非常小的文件,您可以使用 JavaScript 读取并转换为可以作为常规表单数据处理的字符串)。
您需要切换到将 POST 与 CORS(或同源代理)一起使用以禁用同源策略。
无法通过 GET 上传文件。即使您将使用 JSONP。
JSONP 只处理 GET 请求。并且您不能使用 GET 请求上传文件(通常使用 POST 请求上传文件)。
如果你想向某个服务器发送跨域POST请求,那么你应该确定在下一种情况下:
那个服务器应该发给你 header Access-Control-Allow-Origin : *
。另外你可能需要 Access-Control-Allow-Methods: POST
header.
如果它有那些 header,那么您很幸运,您可以 POST 您的数据在此服务器上。
P.S。您可以尝试使用其他方法进行有效的跨域请求。很好 js library easyXDM 跨域请求, 使用不同的方式来做到这一点。
对于跨域工作,您需要这些东西 -
1 :- 您需要服务器的许可。像访问控制允许来源:*.
2 :- 如果你使用 jquery 那么你可以使用 jsonp 方法。
3 :- 如果你想使用普通的 javascript 那么你可以使用这个 link -
How to make a JSONP request from Javascript without JQuery?
JSONP 和 CORS 完全是两个不同的东西。
JSONP
JSON with Padding 只是利用下载 javascript 文件时没有同源策略限制这一事实的黑客攻击。由于您只能下载脚本,我们使用 built-in 数据格式 JSON 而不是 XML 或 HTML。此外,您只能使用 JSONP 发出 GET 请求,因为它所做的只是创建一个 script
并将 src
设置为其他域并将其附加到您的 DOM,一旦它是下载,它被执行,那是当我们的回调用于从原始域调用代码传递 JSON object.
CORS
Cross-origin 资源共享是 W3C 的一项标准,允许从另一个域请求网页上的许多资源(例如字体、JavaScript 等)。您不仅限于使用 GET,还可以使用所有常用的 HTTP 方法,例如 POST、HEAD、PUT、DELETE 和其他
如何发出 CORS 请求:
就像将 AJAX 调用中的 url 更改为其他域一样简单,客户端没有其他更改。
如果您的浏览器支持 CORS,则根据请求的类型 (simple/complex),可能会触发 pre-flight OPTIONS 请求以获取有关方法类型的信息 & content-types 允许用于此域,此 OPTIONS 响应将被缓存。
以后,每当您对其他域进行 AJAX 调用时,浏览器都会在后台发送 Origin
请求 header。例如,如果来自 google 的页面对 facebook 进行 AJAX 调用,则会将类似这样的内容添加到请求 headers
Origin: http://google.com
当 facebook 看到此 header 时,它将检查 google.com 是否在其允许主机的有效列表中,并通过发送以下 header 作为响应来同意这一点。
Access-Control-Allow-Origin: http://google.com
请注意 Origin 和 Allow-Origin headers 中的主机名应该与浏览器匹配接受并根据收到的回复采取行动。您甚至可以通过在 response
中设置以下 headers 来限制允许的方法和自定义 headers
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER
最后回答你的问题,改变你的Ajax定义如下
$.ajax({
url: 'http://some-other-domain.com/upload.php',
data: fa,
contentType: false,
processData: false,
type: 'POST',
success: function(data) {
alert(data);
}
});
由于您只是对文件进行简单的 POST 调用,因此这是一个简单的请求,因此 Allow-Origin header 就足够了。在您的 PHP 中,阅读 Origin
header 检查它是否在您的列表中,并在 Allow-Origin 响应 header 中设置相同的 header 值。我不知道 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
?>
上的更多资源
希望这能回答您的问题:)
正如人们所说 - GET 不是执行此操作的方法。我见过这种通过隐藏的 iFrame 完成的事情。您可能会找到各种 jQuery 插件来实现所需的结果,但我发现了一个名为 "jQuery iFrame Transport"
的插件
https://cmlenz.github.io/jquery-iframe-transport/
希望对你有所帮助。
您不能使用 JSONP 或 GET 请求上传文件。您确定它之前为同一来源工作吗?
您必须发送跨域 XHR 请求才能上传文件。您可以为此使用 JQuery 文件上传。
https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads
我的代码在同一域中工作正常。
但是当我使用 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);
}
});
是否存在概念理解差距或编码问题。
请提出建议。
除了 GET,您不能使用 JSONP 发出任何类型的请求。您不能使用 GET 请求上传文件(除非它是一个非常小的文件,您可以使用 JavaScript 读取并转换为可以作为常规表单数据处理的字符串)。
您需要切换到将 POST 与 CORS(或同源代理)一起使用以禁用同源策略。
无法通过 GET 上传文件。即使您将使用 JSONP。 JSONP 只处理 GET 请求。并且您不能使用 GET 请求上传文件(通常使用 POST 请求上传文件)。
如果你想向某个服务器发送跨域POST请求,那么你应该确定在下一种情况下:
那个服务器应该发给你 header Access-Control-Allow-Origin : *
。另外你可能需要 Access-Control-Allow-Methods: POST
header.
如果它有那些 header,那么您很幸运,您可以 POST 您的数据在此服务器上。
P.S。您可以尝试使用其他方法进行有效的跨域请求。很好 js library easyXDM 跨域请求, 使用不同的方式来做到这一点。
对于跨域工作,您需要这些东西 -
1 :- 您需要服务器的许可。像访问控制允许来源:*.
2 :- 如果你使用 jquery 那么你可以使用 jsonp 方法。
3 :- 如果你想使用普通的 javascript 那么你可以使用这个 link -
How to make a JSONP request from Javascript without JQuery?
JSONP 和 CORS 完全是两个不同的东西。
JSONP
JSON with Padding 只是利用下载 javascript 文件时没有同源策略限制这一事实的黑客攻击。由于您只能下载脚本,我们使用 built-in 数据格式 JSON 而不是 XML 或 HTML。此外,您只能使用 JSONP 发出 GET 请求,因为它所做的只是创建一个 script
并将 src
设置为其他域并将其附加到您的 DOM,一旦它是下载,它被执行,那是当我们的回调用于从原始域调用代码传递 JSON object.
CORS
Cross-origin 资源共享是 W3C 的一项标准,允许从另一个域请求网页上的许多资源(例如字体、JavaScript 等)。您不仅限于使用 GET,还可以使用所有常用的 HTTP 方法,例如 POST、HEAD、PUT、DELETE 和其他
如何发出 CORS 请求:
就像将 AJAX 调用中的 url 更改为其他域一样简单,客户端没有其他更改。
如果您的浏览器支持 CORS,则根据请求的类型 (simple/complex),可能会触发 pre-flight OPTIONS 请求以获取有关方法类型的信息 & content-types 允许用于此域,此 OPTIONS 响应将被缓存。
以后,每当您对其他域进行 AJAX 调用时,浏览器都会在后台发送 Origin
请求 header。例如,如果来自 google 的页面对 facebook 进行 AJAX 调用,则会将类似这样的内容添加到请求 headers
Origin: http://google.com
当 facebook 看到此 header 时,它将检查 google.com 是否在其允许主机的有效列表中,并通过发送以下 header 作为响应来同意这一点。
Access-Control-Allow-Origin: http://google.com
请注意 Origin 和 Allow-Origin headers 中的主机名应该与浏览器匹配接受并根据收到的回复采取行动。您甚至可以通过在 response
中设置以下 headers 来限制允许的方法和自定义 headersAccess-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER
最后回答你的问题,改变你的Ajax定义如下
$.ajax({
url: 'http://some-other-domain.com/upload.php',
data: fa,
contentType: false,
processData: false,
type: 'POST',
success: function(data) {
alert(data);
}
});
由于您只是对文件进行简单的 POST 调用,因此这是一个简单的请求,因此 Allow-Origin header 就足够了。在您的 PHP 中,阅读 Origin
header 检查它是否在您的列表中,并在 Allow-Origin 响应 header 中设置相同的 header 值。我不知道 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
?>
上的更多资源
希望这能回答您的问题:)
正如人们所说 - GET 不是执行此操作的方法。我见过这种通过隐藏的 iFrame 完成的事情。您可能会找到各种 jQuery 插件来实现所需的结果,但我发现了一个名为 "jQuery iFrame Transport"
的插件
https://cmlenz.github.io/jquery-iframe-transport/
希望对你有所帮助。
您不能使用 JSONP 或 GET 请求上传文件。您确定它之前为同一来源工作吗?
您必须发送跨域 XHR 请求才能上传文件。您可以为此使用 JQuery 文件上传。 https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads