egg.js要实现跨域访问,需要安装egg-cors插件
egg-cors的github链接:https://github.com/eggjs/egg-cors
config.default.js配置:
exports.security = {
domainWhiteList: [ 'http://192.168.115.152:3000' ],
};
config.cors = { //解决跨域访问
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS',
credentials: true,
origin: () => '*'//这边不能为*号,需要指定明确的、与请求网页一致的域名
};
关于跨域访问的设置:
CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。
Access-Control-Allow-Credentials: true
另一方面,开发者必须在AJAX请求中打开withCredentials属性。
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。
需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。
所以上面的origin:()=>'*',*号要改成具体请求网页的域名
如果client端使用的是fetch方式发送ajax请求需要注意:
fetch默认不携带cookie
fetch发送请求默认是不发送cookie的,不管是同域还是跨域;那么问题就来了,对于那些需要权限验证的请求就可能无法正常获取数据,这时可以配置其credentials项,其有3个值:
credentials所表达的含义,其实与XHR2中的withCredentials属性类似,表示请求是否携带cookie;
这样,若要fetch请求携带cookie信息,只需设置一下credentials选项即可,例如fetch(url, {credentials: 'include'});
另外egg-cors文档中的这句话需要注意:
If the origin is set, the plugin will follow it to set the Access-Control-Allow-Origin and ignore the security.domainWhiteList. Otherwise, the security.domainWhiteList which is default will take effect as described above.
意思是如果配置表设置了origin,那么域白名单列表将被忽略,否则,白名单列表才会起作用。
另外遇到一个坑,记录一下:
$getJSON()方法是jquery的ajax包装方法,默认并不带cookie,所以以这种方式发起访问服务器是无法收到cookie的
参考:跨域资源共享 CORS 详解