跨域请求的含义
一般的,只要网站的 协议名protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用
利用 JSONP 实现跨域调用
// 服务器 3000 上的请求页面
function jsonpCallback(data) {
console.log("jsonpCallback: " + data.name)
}
$("#submit").click(function() {
var data = {
name: $("#name").val(),
id: $("#id").val()
};
$.ajax({
url: 'http://localhost:3001/ajax/deal',
data: data,
dataType: 'jsonp',
cache: false,
timeout: 5000,
// jsonp 字段含义为服务器通过什么字段获取回调函数的名称
jsonp: 'callback',
// 声明本地回调函数的名称,jquery 默认随机生成一个函数名称
jsonpCallback: 'jsonpCallback',
success: function(data) {
console.log("ajax success callback: " + data.name)
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus + ' ' + errorThrown);
}
});
});
// 服务器 3001 上对应的处理函数
app.get('/ajax/deal', function(req, res) {
console.log("server accept: ", req.query.name, req.query.id)
var data = "{" + "name:'" + req.query.name + " - server 3001 process'," + "id:'" + req.query.id + " - server 3001 process'" + "}"
var callback = req.query.callback
var jsonp = callback + '(' + data + ')'
console.log(jsonp)
res.send(jsonp)
res.end()
})
使用 <script>标签原生实现 JSONP
// 服务器 3000 上的请求页面
<script src = 'http://localhost:3001/jsonServerResponse?jsonp=jsonpCallback'></script>
function jsonpCallback(data) {
console.log("jsonpCallback: "+data.name)
}
// 服务器 3001 上对应的处理函数
app.get('/jsonServerResponse', function(req, res) {
var cb = req.query.jsonp
console.log(cb)
var data = 'var data = {' + 'name: $("#name").val() + " - server 3001 jsonp process",' + 'id: $("#id").val() + " - server 3001 jsonp process"' + '};'
var debug = 'console.log(data);'
var callback = '$("#submit").click(function() {' + data + cb + '(data);' + debug + '});'
res.send(callback)
res.end()
})
// 服务器 3000 上的请求页面
$(function() {
$("#submit").click(function() {
var data = {
name: $("#name").val(),
id: $("#id").val()
};
$.ajax({
type: 'POST',
data: data,
url: 'http://localhost:3001/cors',
dataType: 'json',
cache: false,
timeout: 5000,
success: function(data) {
console.log(data)
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('error ' + textStatus + ' ' + errorThrown);
}
});
});
});
// 服务器 3001 上对应的处理函数
app.post('/cors', function(req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
var data = {
name: req.body.name + ' - server 3001 cors process',
id: req.body.id + ' - server 3001 cors process'
}
console.log(data)
res.send(data)
res.end()
})
Access-Control-Allow-Origin
The origin parameter specifies a URI that may access the resource. The browser must enforce this. For requests without credentials, the server may specify “*” as a wildcard, thereby allowing any origin to access the resource.Access-Control-
Allow-Methods
Specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above.
Access-Control-Allow-Headers
Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.
// 服务器 3000 上的请求页面
<script>
window.frames[0].postMessage(data, '*');
</script>
<iframe src="http://localhost:3000/index.html" style="display:none" frameborder="0"></iframe>
// 服务器 3001 上的页面
<script>
window.onmessage = function(e) {
e = e || event;
alert('我接受到来自外太空的数据:' + e.data);
}
</script>