软件实训项目遇到了一些疑惑,顺便整理整理概念和思路。
0.两大请求类型
浏览器将CORS请求分成两类
简单请求(simple request)和非简单请求(not-so-simple request)。
只要同时满足以下两大条件,就属于简单请求。
(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不一样的。
-----摘自 阮一峰老师 博客
1.跨域三条件(三个作为充分条件,必须满足全部)
1、浏览器限制
2、跨域行为(域名,端口,协议不一样都是跨域)
域名[主域名与子域名也算]不同
端口不同
协议不同
特注:Ip与域名之间网络交互,也属于跨域,如:123.23.23.12 和 www.a.com
3、XHR(XMLHttpRequest请求)
2.解决方案
网上最多讲述的就是方案,但讲原理的甚少;推荐看阮一峰老师的文章去。
[1]从浏览器出发,允许浏览器跨域。
[2]从XHR(XMLHttpRequest)出发。(仅暂列出三点,Google一下,方案还有很多)
A.JSONP:使用方式就不赘述了,但是要注意JSONP只支持GET请求,不支持POST请求。
B.服务器中间代理。将要请求的目标接口在需要使用方项目处封装为接口响应给客户端。
C.开放需要使用方项目自身的跨域网络方案。[针对接口受使用方控制]。
①Spring注解@CrossOrigin实现细化到某个或者某些url(action)映射级别:
②[常用]手动编程设置,可以写成过滤器一类的。以下是常见设置:
set:header('Access-Control-Allow-Origin:*');//允许所有来源访问,* 可以换为origin或者referer:req.getHeader("Origin")更安全一点,有兴趣可以探究一下origin与referer的区别~
set:header('Access-Control-Allow-Method:POST,GET');//允许访问的方式
set:header('Access-Control-Allow-Credentials:true');//服务器端是否允许携带cookie
set:header("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, Authorization, token, Origin");//request允许携带的header
set:header("Access-Control-Max-Age", "3600");
3.哪些情况是跨域?
http://www.123.com/index.html 调用 http://www.123.com/server.php (非跨域)
http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)
http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)
http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)
http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)
注:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
4.概念区分
0.热身问题(见图)
1.浏览器直接输入URL|img(javascript).src|link(a;base).href:不涉及跨域,且:属用户已知又主动
2.在当前网站网页下Ajax请求其他链接:可能涉及跨域,且:用户未知又被动,防止盗传用户数据到其他网站
3.微信小程序请求我方服务器,是否涉及跨域呢?
微信小程序request方法不需要考虑跨域访问问题,因为:微信小程序的做法是由微信官方的服务器取访问我方的服务器,所以实际的“跨域问题”已经在我们的小程序与微信后台交流的时候解决了。
微信官方对应文档:https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html
另外,需注意:微信小程序wx.request不支持获取我方响应给小程序的response.Cookie/Session和Header机制;
但小程序支持发起请求时携带cookie或者控制header。小程序(客户端):要维持会话就需要自己来保存cookie,并且请求的时候加上cookie;我方数据端(服务器端):原自动返回的cookie放在header中已经不行了,服务器端需要额外为小程序显式返回JSESSIONID,保障小程序能维护会话。
如何维护,详见这位博主的博客:微信小程序设置cookie
4.Chrome下的网络调试神器Postman所发的网络请求是否存在跨域问题?
5.不同的ajax请求对象,如何保持会话Session/Cookie的问题[非跨域问题]
如果ajax对象不主动设置xml.withCredentials=true(携带Cookie),则Chrome控制台每new XMLHttpRequest()一次ajax请求对象,就是新建一次会话
6.iframe跨域问题
主要分三类:1、不跨域时 2、主域相同、但子域不同时 3、主域不同
详见博文:iFrame跨域解决办法
5.JavaScript提供的Ajax请求对象到底都提供了哪些接口?
6.参考文献
7.英文备注
Credentials:凭证,凭据