研究了挺久的,从不知道什么是跨域到最终解决问题。
简单说,会产生跨域的异常主要是当前页面域名与页面内直接请求的域名不是同一个域,浏览器就是拦截这种它认为不安全的操作
首先必须明确一点:跨域有两种(1、简单请求,2非简单请求)
这里怎么判定,我直接引用阮老师的分析了:
这里在我的请求中是GET,但是定义了自定义的请求头,Authorization,这里浏览器就会判定为非简单请求。
简单请求按照常规处理就好了。
重点是非简单请求
浏览器会先发送一个method为OPTIONS的请求,这里称之为“预请求”(preflight)
这个preflight是用来跟服务端确认,当前操作是否被服务端允许,确认了一次后之后的就相当于简单请求了,这个preflight的确认频率可以在服务端的max-age的返回头来确定。可以设置为浏览器支持的最大值:24小时,即 86400
这里再引用一下mozilla里面的图
了解整个请求过程就好办了
参考了阮老师的js脚本
我在postMan模拟这个预请求
上一次失败的请求
也是在这里我发现了我设置跨域不成功的原因
url确定是正确的,在浏览器地址栏直接请求是可以的。说明kong里面service和route没设置错
这里想到方法是OPTIONS,地址栏直接输入是GET,应该是route里面的method只代理了get的
因为一开始不知道有预检这个操作,所以就只填了我后端的get方法,后来在Route的设置上加上OPTIONS就好了
这里返回的status也是非200非204,浏览器也会判断为预检不通过
我们也可以在浏览器验证
随便找个不同域名的网站,F12打开开发者工具,在 Console里面输入js脚本(ajax异步请求),回车
js脚本:
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://yourApiUrl");
xhr.setRequestHeader('authority-token', 'xxxx');
xhr.send(null);
xhr.onload = function(e) {
var xhr = e.target;
console.log(xhr.responseText);
}
------
好了,了解清楚原理,设置kong的cors插件的时候就会比较清晰了
先在kong上添加service,然后在service上添加路由routes
添加routes的设置的时候注意要在method上多加上OPTIONS这种类型
我就是踩了这个坑所以一直调不通
然后在service上添加cors插件,service下面的所有routes都允许跨域了,或者你也可以单独在routes里面添加cors插件
请求是先到routes的cors再到service的cors
--------------------------
主要参考文章:
阮一峰的 :《跨域资源共享 CORS 详解》
mozilla里面的CORS原理介绍:《Cross-Origin Resource Sharing (CORS)》
StackOverFlow里面的:《How to avoid the CORS preflight》
KONG 的官方文档 《CORS插件介绍》
关键词:
kong,konga,cors,Access-Control-Allow-Origin,OPTIONS,preflight,跨域,非简单请求mozilla,浏览器预检