前言
好记性不如烂笔头,所以学完跨域之后,我还是老实结合demo来整理一篇跨域实现方式的详记。当然,因为我现在学习阶段,并没有跨域的实战经历,所以这篇整理,纯粹停留在我对跨域的理解层面。
等后面接触到更多跨域知识,以及经历项目实战的跨域处理,有更透彻的进阶理解,就再做跨域知识的补充或跨域实战的记录。
这次说的跨域方式有四种:
1、JSONP
2、 CORS
3、 降域(document.domain)
4、 postMessage
一、为何要跨域——因为“同源策略”
1、什么是跨域
通俗来说,就是两个不同域名的网站的JavaScript脚本的交互。
常见交互有:一方发送请求要获取数据,对方响应并传输数据;操作网站页面的DOM元素等。
2、为何要跨域
现实场景中,肯定有很多时候是需要跨域请求、传输数据的。这些合理的用途会被浏览器默认阻止。
那么重点来了,为什么浏览器会默认阻止跨域操作呢?
因为所有浏览器都奉行“同源策略”。
同源策略:只允许同源的JS脚本(或者说接口)进行交互。不同源的情况下,不能读写对方的任何资源。
举例来说,http://www.jianshu.com
这个网址,http://
协议,www.jianshu.com
是域名,端口号不写的情况下默认是80
。
那么,同源需要满足下面三点,任何一点不同就视为不同源:
1、同协议:常见协议有http://、https://、file://(本地文件)、ftp://协议
2、同域名:比如www.example.com/dir2/other.html和www.example.com/dir/page.html
3、同端口号:URL默认不写端口,默认端口就是80。
(注意默认80端口和8080端口是不同的,两者不等同。)
同源策略是浏览器出于信息安全考虑,防止恶意网站窃取用户数据。
例如用户在登录某一网上银行网站后,又去登录其他恶意网站。如果没有同源策略,恶意网站的后台就可以获取网银网页的用户信息。因为浏览器对提交表单并没有同源策略的限制,假如用户登录网银后忘记退出登录。因为登录密码信息存储在cookie中,恶意网站就可以获取用户登录密码等信息,冒充用户,进行恶意操作。
二、使用Ajax跨域请求失败例子
在讲解跨域实现的方式之前,先来实例演示下,不使用任何跨域方式,只是纯粹ajax技术跨域或同域名请求数据时浏览器会做出的默认举动:
例子:当前页面显示3个新闻标题,点击“换一组”按钮,从指定接口获取数据,随机生成新的3个新闻标题。
index.html文件的代码:
ajax获取数据
- 随机变换新闻标题1
- 随机变换新闻标题2
- 随机变换新闻标题3
在模拟的服务端,返回JSON格式的数据:
app.get('/getNews',function(req,res){
var news=[
"输入内容1",
"输入内容2",
"输入内容3",
"输入内容4",
"输入内容5",
"输入内容6",
"输入内容7",
"输入内容8",
"输入内容9"
]
var data=[];
for(var i=0;i<3;i++){
var index=parseInt(Math.random()*news.length); //随机选择news数组的下标
data.push(news[index]);
}
/*ajax的写法*/
res.send(data);
//console.log(data) //随机得到:[ '输入内容1', '输入内容4', '输入内容3' ]
})
1、同源域名登录的情况
设置host文件,让www.bbhuangyh.com和www.aahuangyh.com
等于127.0.0.1。然后使用http://bbhuangyh.com:8080/
域名登录。此时网页的域名和数据请求接口的域名xhr.open('get','http://bbhuangyh.com:8080/getNews',true)
相同。点击“换一组”按钮,就能从接口返回数据,获取替换页面数据,实现效果。
2、不同源域名登录的情况
数据请求接口的域名是'http://bbhuangyh.com:8080/getNews
,而现在使用localhost:8080
或者http://aahuangyh.com:8080/
这个完全不同的域名(即使实际都是指向127.0.0.1)来登录,点击“换一组”。这种情况下就是,不同源请求获取数据,浏览器会进行阻拦。点击“换一组”的操作无效。
浏览器返回的错误提醒:
XMLHttpRequest cannot load http://bbhuangyh.com:8080/getNews.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:8080' is therefore not allowed access.
三、跨域方法——JSONP
1、JSONP的原理
(1)