以下考虑的场景非前后端分离项目的跨域,就是要请求其他非同源的接口
不考虑域名端口号ip 按协议划分
https =>https/http 可以跨域
http =>http 可以跨域
http =>https 不可以跨域 尝试iframe或者后端转发还有ws..
简单请求足以满足大多数跨域请求
很多时候可能不了解这一点比如我... 如果你不小心使用了json格式
'Content-type':'application/json;charset=utf-8' 都不会满足这个简单请求而被拦截
大多数仅仅是数据交互简单请求已经足够
浏览器将CORS请求分为两类:简单请求(simple request)和非简单请求(not-simple-request),简单请求浏览器不会预检,而非简单请求会预检。
同时满足下列三大条件,就属于简单请求,否则属于非简单请求
-
请求方式只能是:GET、POST、HEAD
-
HTTP请求头限制这几种字段:Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID
-
Content-type只能取:application/x-www-form-urlencoded、multipart/form-data、text/plain
对于简单请求,浏览器直接请求,会在请求头信息中,增加一个origin字段,来说明本次请求来自哪个源(协议+域名+端口)。服务器根据这个值,来决定是否同意该请求,服务器返回的响应会多几个头信息字段,如图所示:上面的头信息中,三个与CORS请求相关,都是以Access-Control-开头。
-
Access-Control-Allow-Origin:该字段是必须的,* 表示接受任意域名的请求,还可以指定域名
-
Access-Control-Allow-Credentials:该字段可选,是个布尔值,表示是否可以携带cookie,(注意:如果Access-Control-Allow-Origin字段设置*,此字段设为true无效)
-
Access-Control-Allow-Headers:该字段可选,里面可以获取Cache-Control、Content-Type、Expires等,如果想要拿到其他字段,就可以在这个字段中指定。
前端满足简单请求 GET POST 设置Content-type
var params = {
"username": 'username',
"content": ''
};
var url = 'http://cjqu4r.natappfree.cc/test2';
// url = 'https://api.doctorxiong.club/v1/stock/kline/day?code=600010';
fetch(url, {
//注释的这些没什么卵用
method: 'POST',
// credentials: 'include',
headers:{
'Accept': '*/*',
// 'Access-Control-Allow-Origin':'*',
// 'Access-Control-Allow-Headers':'*',
// 'Origin':'cjqu4r.natappfree.cc',
'Content-Type':'application/x-www-form-urlencoded'
// 'Content-Type':'text/plain'
// 'Content-type':'application/json;charset=utf-8'
},
// mode: 'cors',
body: JSON.stringify(params)
})
.then(function (response) {
return response.json()
})
.then(function (data) {
console.log(data)
})
后端简单配置跨域 即可实现大多数跨域请求
response.setHeader("Access-Control-Allow-Origin", ((HttpServletRequest) req).getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Disposition,Origin, X-Requested-With, Content-Type, Accept,Authorization,id_token");
response.setHeader("Access-Control-Allow-Credentials","true");
response.setHeader("Content-Security-Policy", "default-src 'self' 'unsafe-inline'; script-src 'self'; frame-ancestors 'self'; object-src 'none'");
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-XSS-Protection", "1; mode=block");
// POST 方式要从流里读数据
InputStream in = request.getInputStream();
BufferedReader bin = new BufferedReader(new InputStreamReader(in,
"utf-8"));
String line = null;
StringBuffer content = new StringBuffer();
while ((line = bin.readLine()) != null) {
content.append(line);
}
System.err.println(content);
JSONObject jsonObject = JSONObject.parseObject(content.toString());
System.err.println(jsonObject.get("username"));
JSONObject json = new JSONObject();
json.put("code", "200");
json.put("msg", "ok");
json.put("args", content.toString());
其他跨域方式
- nodejs项目框架可以设置代理
- 通过jsonp跨域 只能请求GET
- 通过document.domain+iframe来跨子域
- 使用window.name+iframe来进行跨域
- 使用window.postMessage方法来跨域
https引起的跨域问题-COE&casestudy_java_编程一生-DevPress官方社区
js处理的8种跨域方法 - lcspring - 博客园 (cnblogs.com)
(100条消息) 解决iframe跨域跟父级进行通讯问题【postMessage】 重点是跨域进行通讯!_耶稣与梦的博客-CSDN博客_parent.postmessage