1.跨域的相关概念
1.1 什么是跨域
同源策略是由 Netscape 提出的著名安全策略,是浏览器最核心、根本的安全功能,它限制了一个源(origin)中加载文本或者脚本与来自其他源(origin)中资源的交互方式,所谓的同源就是指协议、域名、端口相同。
当浏览器实行一个脚本时会检查是否同源,只有同源的脚本才会实行,如果不同源即为跨域。
域名组成:
1.2 为什么会出现跨域
浏览器的同源策略,出于防范跨站脚本的攻击,克制客户端脚本(如 JavaScript)对不同域的服务进行跨站调用(通常指使用 XMLHttpRequest 哀求)。
1.3 浏览器的同源策略:Same-Origin Policy
- 没有同源策略的危害
防止恶行哀求
案例讲解:
假设有一个黑客叫做小黑,他从网上抓取了一堆美女图做了一个网站,每日访问量爆表。
为了维护网站运行,小黑挂了一张收款码,以为网站不错的可以适当资助一点,可是无奈伸手党太多,小黑的网站入不敷出。
于是他非常生气的在网页中写了一段js代码,使用ajax向淘宝发起登陆哀求,因为很多数人都访问过淘宝,以是电脑中存有淘宝的cookie,不需要输入账号密码直接就主动登录了,然后小黑在ajax回调函数中解析了淘宝返回的数据,得到了很多人的隐私信息,转手一卖,小黑的网站终于盈利了。
如果跨域也可以发送AJAX哀求的话,小黑就真的获取到了用户的隐私并成功获利了!!!
1.4 跨域有哪些限制
- Cookie、LocalStorage 和 IndexDB 无法读取。
- DOM 无法获得。:垂纶网站
- AJAX 哀求不能发送。
1.5 Ajax哀求步调:
(1)创建XMLHttpRequest 对象。
(2)使用open方法设置哀求的参数。open(method, url, 是否异步)。
(3)发送哀求。
(4)注册事件。 注册onreadystatechange事件,状态改变时就会调用。
(5)获取返回的数据,更新UI。
2.JSONP(JSON with Padding)
2.1 概念
原理就是使用了 script 标签不受同源策略的限制,在页面中动态插入了 script,script 标签的 src 属性就是后端 api 接口的地址,并且以 get 的方式将前端回调处理函数名称告诉后端,后端在响应哀求时会将回调返还,并且将数据以参数的情势传递回去。
2.2 核心代码
前端:- var script = document.createElement('script');
- script.src = 'http://127.0.0.1:2333/jsonpHandler?callback=_callback';
- document.body.appendChild(script);
- var _callback = function(obj) {
- for(key in obj) {
- console.log('key: ' + key +' value: ' + obj[key]);
- }
- }
复制代码 后端:- [HttpGet]
- [Route("jsonpForVue")]
- public void GetjsonpForVue(string callback)
- {
- TokenModelJwt tokenModelJwt=new TokenModelJwt(){
- Role="admin",
- Uid=1,
- Work="dsdf"
- };
- //string call = "({" + response + "})";
- string response = string.Format(""name":"{0}"", "zhagnsan");
- var modlestr = JsonConvert.SerializeObject(tokenModelJwt);
- string call = callback + "(" + modlestr + ")";
- Response.WriteAsync(call);
- }
复制代码 2.3 优劣
劣:
- 这种方式只能发生get哀求;
- 确定jsonp的哀求是否失败并不容易,大多数框架的实现都是联合超时时间来判断;
- 不太安全,可能也会受到攻击;
优:
3 Proxy署理
3.1 概念
- vue-cli的proxyTable用的是http-proxy-middleware中间件
- create-react-app用的是webpack-dev-server内部也是用的http-proxy-middleware
- http-proxy-middleware内部用的http-proxy
跨域是浏览器克制的,服务端并不克制跨域
以是浏览器可以发给自己的服务端然后,由自己的服务端再转发给要跨域的服务端,做一层署理。
3.2 核心代码
前端:- proxy: {
- // 配置多个代理
- "/api": {
- target: "http://localhost:5000",//这里改成你自己的后端api端口地址,记得每次修改,都需要重新build
- //target: "http://localhost:58427",
- //target: "http://api.douban.com",
- ws: true,
- changeOrigin: true,
- pathRewrite: {
- // 路径重写,
- "^/apb": "" // 替换target中的请求地址
- }
- }
复制代码
3.3 优劣
缺点:不能用在生产环境,只能在开发环境;
优点:dev环境设置很简朴,支持多个域名;
4 CORS,全称:Cross-Origin Resource Sharing(跨域资源共享)
4.1 概念
CORS是一种允许当前域(origin)的资源被其他域(origin)的脚本哀求访问的机制。
当使用 XMLHttpRequest 发送哀求时,浏览器如果发现违反了同源策略就会主动加上一个哀求头 origin,后端在接受到哀求后确定响应后会在 Response Headers 中参加一个属性 Access-Control-Allow-Origin,值就是发起哀求的源地址(http://127.0.0.1:8888),浏览器得到响应会进行判断 Access-Control-Allow-Origin 的值是否和当前的地址相同,只有匹配成功后才进行响应处理。
简朴哀求
- GET
- HEAD
- POST
- 条件 2:Content-Type 的值仅限于下列三者之一:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
复杂哀求
4.2 核心代码
后端设置
4.3 优劣
缺点:
优点:
- 支持所有 Http 谓词哀求
- 不消注意接口规则
- 可用在生产环境
5 Nginx
概念:nginx解决跨域 是使用其反向署理的能力
5.1 跨域原理
Brower =》 host =》 nginx =》 目的地址服务器数据 =》 nginx =》 Brower
也就是说,nginx并不是通过监听brower的哀求。而是作为一个服务器,接收外部对本机的哀求。以是是先通过host,让哀求指向本机,才会经过nginx。才能进行转发。
- 首先,直接在浏览器地址栏中,输入某接口地址。是不会产生跨域标题的。
- 只有当在某域名的页面中,由该页面发起的接口哀求。才可能会跨域。
- nginx就雷同于这个浏览器地址栏,它接收到外部对它的哀求( 注意,nginx只会接收别人对它的哀求,而不会拦截浏览器的哀求 ),再雷同浏览器地址栏一样去哀求某个接口。最后将哀求到的内容返回回去
5.2 核心代码
- server {
- listen 1005;
- server_name localhost;
- location / {
- root nuxt\Blog.Admin\dist;
- index index.html index.htm;
- }
- location /api {
- rewrite ^.+apb/?(.*)$ /$1 break;
- include uwsgi_params;
- proxy_pass http://localhost:1004; #// 这是 netcore 端口
- }
- error_page 404 /404.html;
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root html;
- }
- }
复制代码 5.3 优劣
缺点:
优点:
- 对独立性强的小项目,使用nginx则可以降低你的开发成本,快速发开快速上线
6 Socket
WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
核心代码:- var ws = new WebSocket('wss://echo.websocket.org'); //创建WebSocket的对象。参数可以是 ws 或 wss,后者表示加密。
- //把请求发出去
- ws.onopen = function (evt) {
- console.log('Connection open ...');
- ws.send('Hello WebSockets!');
- };
- //对方发消息过来时,我接收
- ws.onmessage = function (evt) {
- console.log('Received Message: ', evt.data);
- ws.close();
- };
- //关闭连接
- ws.onclose = function (evt) {
- console.log('Connection closed.');
- };
复制代码 7 其他
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |