关于跨域的一些个人理解,前端跨域问题

网上关于跨域的问题都是千篇一律,今天说说个人的理解,也是因为华哥让搞清楚,不然我自己也没想到细琢磨

  • 什么是跨域

发生跨域问题报错都是浏览器限制,当我们发送一个跨域请求的时候,后台是能接到请求的,而且也正确的返回数据,前台控制台也能看见返回的数据,但是浏览器出于安全考虑会报错,说白了就是浏览器这擅自给拦截了

惯例贴上个表

1

http://www.a.com/a.js
http://www.a.com/b.js

同一域名下

允许

2

http://www.a.com/lab/a.js
http://www.a.com/script/b.js

同一域名下不同文件夹

允许

3

http://www.a.com:8000/a.js
http://www.a.com/b.js

同一域名,不同端口

不允许

4

http://www.a.com/a.js
https://www.a.com/b.js

同一域名,不同协议

不允许

5

http://www.a.com/a.js
http://70.32.92.74/b.js

域名和域名对应ip

不允许

6

http://www.a.com/a.js
http://script.a.com/b.js

主域相同,子域不同

不允许

7

http://www.a.com/a.js
http://a.com/b.js

同一域名,不同二级域名(同上)

不允许(cookie这种情况下也不允许访问)

8

http://www.cnblogs.com/a.js
http://www.a.com/b.js

不同域名

不允许

  • 如何解决跨域问题

只要让浏览器不报错就行,也就是让浏览器解除限制

 

1. document.domain+iframe

对于主域相同而子域不同的例子,可以通过设置document.domain(该方法能够获取当前浏览器地址域名)的办法来解决,也就是上面的第6种情况,具体的做法是可以在

http://www.a.com/a.html和http://script.a.com/b.html两个文件中分别加上document.domain = ‘a.com’;然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以“交互”了。

缺点:      

    1、安全性,当一个站点(b.a.com)被攻击后,另一个站点(c.a.com)会引起安全漏洞。

    2、如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。

既然优缺点,就不建议使用,毕竟现在解决跨域的方法很多,利用代理就很好,而且现象前端主流三大框架都自带代理配置

 

2. 动态创建script标签(也就是通常所说的jsonp)

浏览器禁止跨域只是针对发送的请求类型为     xhr    请求,而script标签发送的请求类型是    script   ,  不会被限制,一般情况下都是发送的xmlhttpRequest请求有跨越问题,其中type类型为xhr,比如<img>标签的src后面的地址发送的请求是json请求,就不会报错

jsonp方法需要后台配合,Jsonp请求发出去的时候加了一个callback(也可以是callback2或callback3,这个需要前后端约定一致就行)参数,后台发现有callback参数,就知道这是一个jsonp请求,然后就会把返回的参数由json变为javascript,也就是一个js代码块,而js代码的内容就是callback值作为函数名,返回的数据作为函数的参数

下面的图片为发生jsonp请求的时候jquery动态创建的script脚本,用完就销毁

这个参数是为了防止请求被缓存的,ajax请求中加上catch:true可用把那个参数禁掉,表示可以被缓存

jsonp有什么弊端

    1. 最大的弊端就是只支持get请求

    2.如果服务器不是自己的,改起来也麻烦

 

3. CORS(跨域资源共享)

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

简单请求,对于简单请求,在头信息之中,增加一个Origin字段。Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。

Origin: http://api.bob.com, 也可以用 * 代表全部

Host: api.alice.com

Accept-Language: en-US

Connection: keep-alive

User-Agent: Mozilla/5.0...

如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。

Access-Control-Allow-Origin: http://localhost:8081   表示接受某某域名的请求

Access-Control-Allow-Credentials: true             表示是否允许发送Cookie

Content-Type: text/html; charset=utf-8

后台添加代码

非简单请求

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。

上面的是一个非简单请求,第一次先发送一个type为options的预检命令,当预检命令通过后,在发送第二次请求

后台代码加入这个代码,表示在一个小时内可以用缓存的预检命令,不需要再次发送,减轻浏览器负担

下图代表发送请求带上cookie

 

4.nginx反向代理

反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

使用代理,可以访问一些我们所不能直接访问到的网络,或者可以隐藏自己的真实身份

安装ngnix,

配置代理服务器,

发送跨域请求

此方法不需要服务器配合

关于nginx反向代理的配置网上文章很多,这里不不列举了

但是个人遇到的问题是在使用react项目的时候,利用nginx时,由于要本地的4444端口访问服务器,需要监听(listen)本地的4444端口,此时nginx运行在4444端口上,但是本地的react项目也要运行在4444端口上,会造成端口冲突问题,一直没解决,后来找到了react里面自带的proxy代理。

 

5. apache做反向代理服务器

原理与上面一样,

nginx相对于apache更轻量级,占用内存资源少

一般来说,需要性能的web 服务,用nginx 。如果不需要性能只求稳定,那就apache 

在高连接并发的情况下,Nginx优于Apache

nginx处理静态文件好,耗费内存少

Apache处理动态文件好

 

6. web sockets

web sockets是一种浏览器的API,需要浏览器支持HTML5它的目标是在一个单独的持久连接上提供全双工、双向通信。

web sockets原理:在JS创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockt协议。

试用场景--只有在支持web socket协议的服务器上才能正常工作。

 

7. location.hash

利用url地址hash值改变但不刷新页面的特性可以利用hash值来进行数据传递在a.html下嵌套一个不同域的b.html在b页面中增加一个和a同域的iframe(c.html)来做代理a能修改b的hash值这样b可以修改chash值,c又能修改a的hash值,做到让b向a传输信息(当然本质上是b向c,c再向a传输)

缺点——可传递的数据类型、长度均受限,数据还是直接显示在url上的,不够安全。实现也较麻烦,还要搞setInterval不断监听。

对于本项目(接口仿真测试-react),建议使用第三种方法CORS,后台定向设置允许哪个ip访问,既能保证安全性问题,又能解决跨域问题

【右上角点个赞,谢谢】

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值