1. 概念
同源策略是浏览器的一种安全策略,所谓铜元素是指域名、协议、端口完全相同,只有同源的地址才可以通过Ajax的方式去请求,同源或者不同源说的是两个地址之间的关系,不同源地址之间请求称为跨域请求。
跨域请求:img的src可以发送不同源地址之间的请求,但无法拿到请求结果;link(链入一个文档,通过rel属性申明链入的文档与当前文档之间的关系)同上;下面是借助JavaScript实现跨域请求。
<script>
// 可发送不同源地址之间的请求,无法拿到响应结果,借助于能够作为js执行
var script = document.createElement('script');
script.src = 'http://localhost/time2.php';
document.body.appendChild(script);
function foo(res) { // 相当于请求的回调
console.log(res);
}
</script>
time2.php
<?php
header('Content-Type: application/javascript');
$json = json_encode(array(
'time' => time()
));
echo "foo({$json})";
2. JSONP
JSON with Padding,跨域请求技巧,通过script标签请求一个服务器的PHP文件,这个文件返回的结果是一段JS,作用是调用我们事先定义好的一个函数,从而将服务端想要给客户端发过去的数据发送给客户端。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
function jsonp(url, params, callback) {
var funcName = 'jsonp_' + Date.now() + Math.random().toString().substr(2,5);
if(typeof params == 'object') { // 以对象方式传递参数
var arr = [];
for(var key in params) {
var value = params[key];
arr.push(key + '=' + value);
}
params = arr.join('&');
}
var script = document.createElement('script');
script.src = url + '?callback=' + funcName;
document.body.appendChild(script);
window[funcName] = function(data) {
callback(data);
delete window[funcName];
document.body.removeChild(script);
}
}
jsonp('http://localhost/server.php', {id: 1}, function(res) {
console.log(res);
});
</script>
</body>
</html>
server.php
<?php
$data = array(
array(
'id' => 1,
'name' => 'Karry',
'age' => 21
),
array(
'id' => 2,
'name' => 'Roy',
'age' => 20
),
array(
'id' => 3,
'name' => 'Yee',
'age' => 20
)
);
if(empty($_GET['callback'])) {
header('Content-Type: application/json');
echo json_encode($data);
exit();
}
header('Content-Type: application/javascript');
$result = json_encode($data);
$callback_name = $_GET['callback'];
echo "typeof {$callback_name} == 'function' && {$callback_name}({$result})";
jQuery中的jsonp
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$.ajax({
url: 'http://localhost/server.php',
dataType: 'jsonp',
success: function(res) {
console.log(res);
}
})
</script>
3. CORS
Cross Origin Resource Share,跨域资源共享,只需在被请求的服务器响应的时候添加如下代码,表示这个资源是否允许指定域请求。
header('Access-Control-Allow-Origin: *');