跨域
为了保证一定的安全性,浏览器的同源策略会阻止跨域请操作。
只要协议、域名、端口有任何一个不同,都被当作是不同的域,之间的请求就是跨域操作
但是这个随即成为了前端开发者(尤其是我这种新手)心中永远的痛。一旦请求接口就会浏览器直接卡死发出的请求。
现如今的跨域解决方案有如下的两种方案:
1. JSONP跨域。说白了就是利用script标签没有跨域限制的条件来达到与第三方通讯的目的,
JSONP是一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据。
2. CORS跨域资源共享,是W3C的一个标准。它允许浏览器向不同源的服务器进行XMLHttpRequest请求。CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
跨域解决
了解了这个,似乎一切就已经迎刃而解了。我们只要在服务端添加header请求头允许跨域访问就好了。我用的是tp5.1开发的数据接口,按照网上给的解决方案,我在public文件夹里面的index.php入口文件中添加了如下代码:
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,PATCH');
header("Access-Control-Allow-Headers:DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, Accept-Language, Origin, Accept-Encoding");
这样前端发出的GET请求被拦截的问题就解决了。但是正当我沾沾自喜的时候,又出现了问题:当我发送POST请求到后端时候浏览器直接报错:
这个错误很莫名其妙,网上搜也是各种不同的解释。
直到我看到了廖雪峰大神的博客:
CORS是分为简单请求和非简单请求两种不同的形式的。POST请求当然是是属于简单请求的范畴,但是我忽视了post数据的数据类型,我发送的数据是:(application/json ) 格式的!这就直接使我的请求变成了非简单请求。
当浏览器发出非简单请求的CORS的时候,会在正式通信之前发送一次HTTP查询请求,也就是“预检”请求:
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
由于我服务端配置的不完善。导致预检请求时候就报错。所以当前的解决方案有两种:
1. 服务端重新配置。
2. POST数据时将数据格式改成简单格式。
由于我服务端的水平不太好,以知识了好多种解决方案也不行。所以我就直接在POST数据时,将数据格式改成了简单请求的“Content-Type”就可以了:
通过引入
import qs from ‘qs’ 包,用qs.stringify()将对象 序列化成URL的形式,以&进行拼接。这样就改变了Content-Type的格式:
这样就可以愉快地进行跨域操作了。