0%

前端跨域深入


跨域想必大家都不陌生,解决的方法之前的博客也有提到,今天来一起学习一下,跨域的时候,浏览器做了哪些操作,后台的服务器能否收到前端在跨域时发出的参数

跨域的原因就不在重复的描述了,今天了解一下两点,浏览器同源政策及跨域资源共享

浏览器同源政策

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

同源政策共有三种行为受到限制

  • Cookie、LocalStorage 和 IndexDB 无法读取。
  • DOM 无法获得。
  • AJAX 请求不能发送。

提交表单不受同源政策的限制。

其实很好理解的,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。由此可见,”同源政策”是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。

跨域资源共享CORS(Cross-origin resource sharing)

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。稍后通过一些例子来具体说明

CORS请求

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

一丶请求方法是以下三种方法之一

  1. HEAD
  2. GET
  3. POST

二丶HTTP的头信息不超出以下几种字段

  1. Accept
  2. Accept-Language
  3. Content-Language
  4. Last-Event-ID
  5. Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

凡是不同时满足上面两个条件,就属于非简单请求。浏览器对这两种请求的处理,是不一样的。

简单请求

假设有一个post请求,是一个简单请求

1
2
3
4
5
6
7
8
9
10
11
12
$.post({
url: 'http://127.0.0.1:3000/ceshi',
data: {
name: '我是谁'
},
success: function(resData) {
console.log(resData);
},
error:function(resData){
console.log(resData);
}
})

对应的服务端代码为(详细的代码就不贴出来了,之前的博客有)

1
2
3
4
5
6
7
app.post('/ceshi',function(req,res){
console.log(req.body)
res.send({
code:'success',
message:'你好'
})
})

这时服务器并没有设置允许跨域,前端浏览器发现跨域,返回了提示,但是,后端的服务器是可以接受到前端传过来的值的

非简单请求

将上面的请求稍微改一下,添加一个contentType: ‘application/json’

1
2
3
4
5
6
7
8
9
10
11
12
13
$.post({
url: 'http://127.0.0.1:3000/ceshi',
contentType: 'application/json',
data: {
name: '我是谁'
},
success: function(resData) {
console.log(resData);
},
error:function(resData){
console.log(resData);
}
})

服务器就接受不到前端传递的参数了,这是为什么呢,同样都是跨域,为什么一个收的到,一个却不行

因为非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

当服务端允许跨域后

1
2
3
4
5
6
7
8
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
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");
next();
});

服务器返回的响应,会多出几个头信息字段。

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Origin, X-Requested-With, Content-Type, Accept
Content-Type: text/html; charset=utf-8

好了,以上就是我对跨域的一些理解,如果文章由于我学识浅薄,导致您发现有严重谬误的地方,请一定在评论中指出,我会在第一时间修正我的博文,以避免误人子弟。

-------------本文结束感谢您的阅读-------------
没办法,总要恰饭的嘛~~