什么是跨域?
概念:只要协议、域名、端口有任何一个不同,都被当作是不同的域。对于端口和协议的不同,只能通过后台来解决。
URL 说明 是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js 同一域名下 允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js 同一域名下不同文件夹 允许
http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名,不同端口 不允许
http://www.a.com/a.js
https://www.a.com/b.js 同一域名,不同协议 不允许
http://www.a.com/a.js
http://70.32.92.74/b.js 域名和域名对应ip 不允许
http://www.a.com/a.js
http://script.a.com/b.js 主域相同,子域不同 不允许
http://www.a.com/a.js
http://a.com/b.js 同一域名,不同二级域名 不允许
http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允许
跨域解决方法:
1.后端代理
$ajax({
url: 'http://localhost:8088/JS2004/Day%2023_jsonp/3.file.php',
success: function(data) {
console.log(JSON.parse(data));
}
});
<?php
$data = file_get_contents('http://api.k780.com/?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json');
//后端不存在跨域,因为是服务器端
//php下面的函数,获取对应地址的数据
echo $data;
?>
2.动态创建script
script标签的src不存在跨域,加载数据。(数据填充在一个函数内部)
function loadScript(url, func) {
var head = document.head || document.getElementByTagName('head')[0];
var script = document.createElement('script');
script.src = url;
script.onload = script.onreadystatechange = function(){
if(!this.readyState || this.readyState=='loaded' || this.readyState=='complete'){
func();
script.onload = script.onreadystatechange = null;
}
};
head.insertBefore(script, 0);
}
window.baidu = {
sug: function(data){
console.log(data);
}
}
loadScript('http://suggestion.baidu.com/su?wd=w',function(){console.log('loaded')});
//我们请求的内容在哪里?
//我们可以在chorme调试面板的source中看到script引入的内容
3.跨域资源共享(CORS)
原理:服务器设置Access-Control-Allow-Origin HTTP响应头之后,浏览器将会允许跨域请求
CORS是HTML5标准提出的跨域资源共享(Cross Origin Resource Share),支持GET、POST等所有HTTP请求。CORS需要服务器端设置Access-Control-Allow-Origin
头,否则浏览器会因为安全策略拦截返回的信息。
配置文件:
Access-Control-Allow-Origin: * # 允许所有域名访问,或者
Access-Control-Allow-Origin: http://a.com # 只允许所有域名访问
4.JSONP跨域
原理:<script>
是可以跨域的,而且在跨域脚本中以直接回调当前脚本的函数
script标签是可以加载异域的JavaScript并执行的,通过预先设定好的callback函数来实现和母页面的交互。它有一个大名,叫做JSONP(JSON with Padding)跨域。它是一个非官方的协议,明明是加载script,为什么和JSON扯上关系呢?原来就是这个callback函数,对它的使用有一个典型的方式,就是通过JSON来传参,即将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。JSONP只支持GET请求。
前端代码:
<script type="text/javascript">
function dosomething(jsondata){
//处理获得的json数据
}
</script>
<script src="http://haorooms.com/data.php?callback=dosomething"></script>
后端代码:
<?php
$callback = $_GET['callback'];//得到回调函数名
$data = array('a','b','c');//要返回的数据
echo $callback.'('.json_encode($data).')';//输出
?>
【回调函数】
函数当参数,传递另外一个函数
使用回调函数的地方:
数组的新方法:every some filter map forEach...
定时器
缓冲运动
封装的ajax