你需要知道的前端跨域知识(同源、正向代理、反向代理、前端代理、nignx反向代理)
一、什么是跨域?
当一个请求url的协议名、主机号、端口号三者任意一个或多个与当前url不同,即可称为跨域。
二、为什么会出现跨域问题?
一般产生跨域的原因是浏览器的同源策略的限制。
同源策略:是一种约定,是浏览器最核心最基本的安全功能,它会阻止一个域的js脚本和另一个域的内容进行交互。
如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。
同源,即两个页面具有相同的协议名、主机和端口号
三、非同源会出现哪些限制?
- 无法读取非同源网站的cookie、localStorage等
- 无法接触非同源网站的DOM和js对象
- 无法向非同源网站发送Ajax请求
四、跨域的解决方案
4.1 JSONP跨域
原理
JSONP是利用了script标签没有跨域限制的这一特性,它可以通过src属性填写目的地址,发送一个带回调参数的get请求,向服务器请求JSON数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
缺点
只支持get请求,不支持post请求,适用于加载不同域名的js、css、img等静态资源
实现跨域
1、原生实现
2、vue.js
4.2 CORS(跨域资源共享)
通俗理解:当你想从不同的源获取公共资源时,资源提供服务器需要告诉浏览器“请求来自的这个源可以访问我的资源”。浏览器记住这一点并允许跨源资源共享。
有几个关键的响应头字段:
a、Access-Control-Allow-Origin:必填,表示可以允许请求的来源。可以填写具体的源名称,也可以填写*表示允许任何源请求。
b、Access-Control-Allow-Methods:表示允许的请求方法列表。
c、Access-Control-Allow-Credentials:一个布尔值,表示是否允许发送cookie。默认情况下,cookie 不包含在 CORS 请求中。如果设置为 true,则表示服务器具有显式权限。Cookies 可以包含在请求中并一起发送到服务器。
d、Access-Control-Allow-Headers:其指明了实际请求中允许携带的首部字段。CORS请求时,XMLHttpRequest对象的getresponseheader()方法只能获取六个基本字段:缓存控制、内容语言、内容类型、过期时间、最后修改时间和pragma。如果要获取其他字段,则必须在访问控制公开标头中指定它们。
e、Access-Control-Max-Age:预检请求的有效期。在此期间,无需再次发送预检请求。
普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置。
携带cookie跨域请求:前后端都需要设置。
4.3 nginx反向代理
nginx在应用程序中的作用
nginx是一个高性能的HTTP和反向代理服务器,也是一个通用的TCP/UDP代理服务器。
- 解决跨域
- 请求过滤
- 配置gzip
- 负载均衡
- 静态资源服务器nginx现在几乎是众多大型网站必备的技术,大多数情况下,我们不需要亲自去配置它。##### 理解代理> 代理是在服务器和客户端之间假设的一个服务器,代理将接收客户端的请求并转发给服务器,然后接收服务器的响应转发给客户端。##### 正向代理和反向代理> 正向代理是位于一个客户端和原始服务器之间的服务器,客户端会向这个服务器发送一个请求并指定目标服务器(即原始服务器),然后代理转发请求到目标服务器,并将目标服务器返回的内容转发给客户端。 正向代理是为客户端服务的,客户端可以根据正向代理访问到它本身无法访问到的服务器资源。> 反向代理(Reverse Proxy),是指以代理服务器来接收Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器返回的内容返回给Internet上请求连接的客户端。 反向代理是为服务器服务的,可以帮助服务器接收客户端的请求,帮助服务器做请求转发,负载均衡等。
正向代理是代理客户端,反向代理是代理服务器。
nginx基本配置结构
events{
}
http{
server{
location path
{
...
}
location path
{
...
}
}
server{
...
}
}
- events:配置影响nginx服务器与用户的网络连接
- http:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。
- server:配置多个虚拟主机的相关参数,一个http可以有多个server
- location:配置请求的路由,以及各种页面的处理情况
- upstream:配置后端服务器的具体地址,在负载均衡配置不可或缺。
nginx解决跨域的原理
- 前端的域名为:bc.server.com
- 后端服务的域名为:dev.server.com
现在如果bc.server.com向dev.server.com发请求一定会出现跨域问题。
现在我们只需要启动一个nginx服务器,将server_name 设置为bc.server.com,然后设置相应的location以拦截前端需要跨域的请求,最后将请求代理回dev.server.com,如:
server{
listen 80;
server_name bc.server.com;
location /{
proxy_pass dev.server.com;
}
}
//这样就可以绕过浏览器的同源策略
请求过滤
nginx可以对客户端发送的请求进行过滤,来保护后端服务器的安全
- 根据URL名称过滤,精准匹配URL,不匹配的URL全部重定向到主页。
location /{ rewrite ^.*$ /index.html redirect;}
- 根据状态码过滤
- 根据请求类型过滤
配置gzip
gzip是规定的三种标准HTTP压缩格式之一。
启用 gzip需要服务器和客户端的支持,如果客户端支持对gzip的解析,那服务端只要返回gzip的文件就可以启用gzip了。
如何知道客户端是否支持gzip呢?
通过在请求头的 Accept-Encoding 来标识对压缩的支持。
Accept-Encoding:gzip
我们可以通过nginx的配置来让服务器支持gzip,在响应头中
content-encoding:gzip
,指服务端开启了gzip的压缩方式。
nginx配置
gzip on;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_min_length 1000;
gzip_types text/csv text/xml text/css text/plain text/javascript application/javascript application/json application/xml;
- gzip :开启或关闭gzip模块,默认为off
- gzip_http_version:启用Gzip所需的http最低版本,默认值为HTTP1.1
- gzip_comp_level:压缩级别,级别越大压缩率越大,压缩时间也越长,默认为1,取值为1-9
- gzip_min_length:设置允许压缩的页面最小字节数,默认为0,当设置的值较小时,压缩后的长度可能回避原来的大,建议设置1000以上
- gzip_types:要采用gzip压缩的文件类型,默认为text/html#### 负载均衡> 负载均衡就是用来帮助我们将众多的客户端请求合理的分配到各个服务器,以达到服务端资源的充分利用和更少的请求时间。##### nginx如何进行负载均衡?在upstream指定后端服务器地址列表
upstream balanceServer{ server 10.1.22.31:1234; server 10.1.22.32:1234; server 10.1.22.33:1234;}
在server中拦截响应请求,并将请求转发到upstream配置的服务器列表server{ server_name bc.server.com; listen 80; location /api{ proxy_pass http://balanceServer; }}
##### nginx实现负载均衡的策略- 轮询策略> 默认情况下的策略,将所有客户端请求轮询分配给服务器,但是如果其中某一台服务器压力太大,出现延迟,会影响所有配置在这台服务器的用户- 最小连接数策略> 将请求分配给压力最小的服务器,平衡每个队列的长度- 最快响应速度策略> 依赖于nginx Plus,优先分配给响应时间最短的服务器#### 静态资源服务器匹配以png|gif|jpg|jpeg为结尾的请求,并将请求转发到本地路径.同时也可以进行一些缓存设置.location ~* \.(png|gif|jpg|jpeg)$ { root /root/static/; autoindex on; access_log off; expires 10h;}
五、我在vue项目中的代理方法
项目上线部署之后如果满足同源策略是不会产生跨域问题的,但是在前后端分离的主流模式下,开发时就一定会碰见跨域问题。
利用dev-server实现跨域的原理:
将所有的ajax请求发送给devServer服务器,再由devServer做一次转发,发送给服务器,由于ajax请求是发送给devServer的,所以不存在跨域问题,而devServer是用node平台发送的http请求,自然也不存在跨域问题,借助这一特性,我们可以借助node监听web服务器开启的端口,实现代理转发。
在vue.config.js文件中配置devserver实现跨域
devServer:{proxy:{'/api':{//代表path为api开头的api做代理转发target:'http://xxxxxxx',//设置需要访问的协议域名端口号changeOrigin:true,//允许将主机头的来源设置为目标url,即设置跨域pathRewrite:{'^/api':''//重写url的path部分}}}}
参考文章&&推荐阅读
前端开发者必备的nginx知识
版权归原作者 Bcoovo 所有, 如有侵权,请联系我们删除。