JSONP和CORS跨域请求
2018-02-07 本文已影响114人
xiaoxiaoxiao8
跨域是由于浏览器的同源策略导致的。
什么是同源?
- 协议相同
- 域名相同
- 端口相同
注: 三个都必须满足
什么是同源策略?
同源策略(Same origin policy)是由Netscape提出的一个安全策略,它是浏览器最核心也最基本的安全功能。
同源策略包括:
- DOM同源策略:禁止对不同源页面DOM进行操作;
- XmlHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。
所以,不同源之间的请求就属于跨域请求。
JSONP和CORS是解决跨域请求的两种方法。
JSONP是通过动态创建script标签,然后利用src属性进行请求,这种做法不受同源政策限制。
我举个例子:
用php写个测试接口(test.php)放在93端口目录:
<?php
$result = array(
'code' => 200,
'msg' => 'success'
);
if($_GET['callback'])
echo ';'. $_GET['callback'] . '(' . json_encode($result) .')';
else
echo json_encode($result);
写个请求页面(json.html)放在80端口目录:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONP</title>
</head>
<body>
</body>
<script type="text/javascript">
function handleResponse(response){
console.log(response);
}
window.onload = function() {
var script = document.createElement("script");
script.src = "http://localhost:93/cors.php?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);
};
</script>
</html>
CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。利用 Access-Control-Allow-Origin 响应头解决跨域请求,它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。可以看看阮一峰CORS 详解
此时需要修改test.php:
<?php
header("access-control-allow-origin: http://localhost");
$result = array(
'code' => 200,
'msg' => 'success'
);
if($_GET['callback'])
echo ';'. $_GET['callback'] . '(' . json_encode($result) .')';
else
echo json_encode($result);
写个请求页面(cors.html)放在80端口目录:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>cors</title>
</head>
<body>
</body>
<script type="text/javascript">
window.onload = function() {
var xhr = new XMLHttpRequest();
xhr.open('get', 'http://localhost:93/cors.php');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304) {
console.log(xhr.responseText);//从服务器获得数据
}
};
xhr.send();
};
</script>
</html>
CORS与JSONP对比:
- 1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
- 2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
- 3、 JSONP也被一些老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。