如何通过JavaScript发送跨域POST请求?
注释-它不应该刷新页面,然后我需要抓取并解析响应。
如何通过JavaScript发送跨域POST请求?
注释-它不应该刷新页面,然后我需要抓取并解析响应。
当前回答
CORS是为你准备的。 CORS是“跨域资源共享”,是一种发送跨域请求的方式。现在XMLHttpRequest2和Fetch API都支持CORS,它可以发送POST和GET请求
但它也有局限性。服务器需要指定Access-Control-Allow-Origin,不能设置为“*”。
如果你想要任何origin都可以发送请求给你,你需要JSONP(也需要设置Access-Control-Allow-Origin,但可以是'*')
对于很多请求方式,如果你不知道如何选择,我认为你需要一个完整的功能组件来做到这一点。让我介绍一个简单的组件https://github.com/Joker-Jelly/catta
如果你正在使用现代浏览器(> IE9, Chrome, FF, Edge等),非常建议你使用一个简单但美丽的组件https://github.com/Joker-Jelly/catta.It没有依赖,小于3KB,它支持Fetch, AJAX和JSONP与相同致命的示例语法和选项。
catta('./data/simple.json').then(function (res) {
console.log(res);
});
它还支持所有方式导入到您的项目,如ES6模块,CommonJS,甚至HTML中的<script>。
其他回答
如果您控制远程服务器,您可能应该使用CORS,如回答中所述;它在IE8及以上版本,以及FF、GC和Safari的所有最新版本中都得到支持。(但是在IE8和ie9中,CORS不允许你在请求中发送cookie。)
所以,如果你不控制远程服务器,或者你必须支持IE7,或者你需要cookie并且你必须支持IE8/9,你可能会想要使用iframe技术。
创建一个名称唯一的iframe。(iframes为整个浏览器使用全局名称空间,因此请选择其他网站不会使用的名称。) 构造一个带有隐藏输入的表单,以iframe为目标。 提交表单。
下面是示例代码;我在IE6、IE7、IE8、IE9、FF4、GC11和S5上进行了测试。
function crossDomainPost() {
// Add the iframe with a unique name
var iframe = document.createElement("iframe");
var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
document.body.appendChild(iframe);
iframe.style.display = "none";
iframe.contentWindow.name = uniqueString;
// construct a form with hidden inputs, targeting the iframe
var form = document.createElement("form");
form.target = uniqueString;
form.action = "http://INSERT_YOUR_URL_HERE";
form.method = "POST";
// repeat for each parameter
var input = document.createElement("input");
input.type = "hidden";
input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
小心!您不能直接读取POST的响应,因为iframe存在于一个单独的域中。帧不允许与来自不同域的帧相互通信;这是同源策略。
如果你控制远程服务器,但你不能使用CORS(例如,因为你在IE8/IE9上,你需要使用cookie),有一些方法可以绕过同源策略,例如使用window。postMessage和/或允许你在旧浏览器中发送跨域跨帧消息的库之一:
汽门 XSSInterface EasyXDM jQuery PostMessage插件
如果不控制远程服务器,就不能读取POST的响应,句号。否则会导致安全问题。
还有一种方法(使用html5特性)。你可以使用代理iframe托管在另一个域上,你用postMessage发送消息到那个iframe,然后iframe可以做POST请求(在同一个域上)和postMessage返回到父窗口。
sender.com上的家长
var win = $('iframe')[0].contentWindow
function get(event) {
if (event.origin === "http://reciver.com") {
// event.data is response from POST
}
}
if (window.addEventListener){
addEventListener("message", get, false)
} else {
attachEvent("onmessage", get)
}
win.postMessage(JSON.stringify({url: "URL", data: {}}),"http://reciver.com");
Iframe在reciver.com上
function listener(event) {
if (event.origin === "http://sender.com") {
var data = JSON.parse(event.data);
$.post(data.url, data.data, function(reponse) {
window.parent.postMessage(reponse, "*");
});
}
}
// don't know if we can use jQuery here
if (window.addEventListener){
addEventListener("message", listener, false)
} else {
attachEvent("onmessage", listener)
}
我认为最好的方法是使用XMLHttpRequest(例如:jQuery中的$.ajax(), $.post())与跨起源资源共享polyfills之一https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills#wiki-CORS
高水平……您需要在服务器上设置cname,以便other-ser.your-server.com指向other-server.com。
您的页面动态地创建了一个不可见的iframe,它充当您到other-server.com的传输。然后,您必须通过JS从您的页面与other-server.com通信,并使用回调将数据返回到您的页面。
可能,但需要your-server.com和other-server.com的协调
我知道这是一个老问题,但我想分享我的方法。我使用cURL作为代理,非常简单和一致。创建一个名为submit.php的php页面,并添加以下代码:
<?
function post($url, $data) {
$header = array("User-Agent: " . $_SERVER["HTTP_USER_AGENT"], "Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
$url = "your cross domain request here";
$data = $_SERVER["QUERY_STRING"];
echo(post($url, $data));
然后,在你的js(这里是jQuery):
$.ajax({
type: 'POST',
url: 'submit.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});