跨域想必大家都不陌生,解决的方法之前的博客也有提到,今天来一起学习一下,跨域的时候,浏览器做了哪些操作,后台的服务器能否收到前端在跨域时发出的参数
跨域的原因就不在重复的描述了,今天了解一下两点,浏览器同源政策及跨域资源共享
浏览器同源政策
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
同源政策共有三种行为受到限制
- Cookie、LocalStorage 和 IndexDB 无法读取。
- DOM 无法获得。
- AJAX 请求不能发送。
提交表单不受同源政策的限制。
其实很好理解的,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。由此可见,”同源政策”是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。
跨域资源共享CORS(Cross-origin resource sharing)
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。稍后通过一些例子来具体说明
CORS请求
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
一丶请求方法是以下三种方法之一
- HEAD
- GET
- POST
二丶HTTP的头信息不超出以下几种字段
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。浏览器对这两种请求的处理,是不一样的。
简单请求
假设有一个post请求,是一个简单请求
1 | $.post({ |
对应的服务端代码为(详细的代码就不贴出来了,之前的博客有)
1 | app.post('/ceshi',function(req,res){ |
这时服务器并没有设置允许跨域,前端浏览器发现跨域,返回了提示,但是,后端的服务器是可以接受到前端传过来的值的
非简单请求
将上面的请求稍微改一下,添加一个contentType: ‘application/json’
1 | $.post({ |
服务器就接受不到前端传递的参数了,这是为什么呢,同样都是跨域,为什么一个收的到,一个却不行
因为非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
当服务端允许跨域后
1 | app.all('*', function(req, res, 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
好了,以上就是我对跨域的一些理解,如果文章由于我学识浅薄,导致您发现有严重谬误的地方,请一定在评论中指出,我会在第一时间修正我的博文,以避免误人子弟。