Nginx——反向代理-解决前端跨域问题

目录
前言
一、什么是跨域?
1、什么是同源策略及其限制内容?
2、常见跨域场景
二、nginx反向代理解决跨域问题
1、nginx配置文件(简单版)
2、配置文件注意点
1)proxy_pass对 URI 的处理(重点)
2)proxy_pass指令的URL变量末尾是否加 “ / ”问题
3、URL与URI的区别与联系
4、Location用法总结
5、 Rewrite 用法总结
前言 前后端数据的交互经常会遇到请求跨域问题,小编最近在工作中就遇到了这个问题,最后通过nginx反向代理解决 。
备注:该博客部分概念内容参考自网络 。
一、什么是跨域?1、什么是同源策略及其限制内容? 【Nginx——反向代理-解决前端跨域问题】同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击 。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源 。

同源策略限制内容有:

  • Cookie、LocalStorage、IndexedDB 等存储性内容
  • DOM 节点
  • AJAX 请求发送后,结果被浏览器拦截了
但是有三个标签是允许跨域加载资源:
2、常见跨域场景 当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域 。不同域之间相互请求资源,就算作“跨域” 。常见跨域场景如下图所示:

参考文献:https://segmentfault.com/a/1190000018017118 (九种跨域方式实现原理)
二、nginx反向代理解决跨域问题 1、nginx配置文件(简单版) #负载均衡:设置代理的服务器列表 可设置多个(目标访问地址)
upstream hellonginx {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
server {
#监听端口80也就是直接访问的URL的端口
listen80;
#设置监听的域名 可设置多个(客户端直接访问的地址)
server_namenginx.test.comnginx.test02.com;
#编码格式
charset utf-8;
#代理配置超时、头信息等参数 可以不配置
proxy_connect_timeout 180;
proxy_send_timeout 180;
proxy_read_timeout 180;
proxy_set_header Host $host;
proxy_set_header X-Forwarder-For $remote_addr;
#反向代理路径(和upstream绑定)
location / {
proxy_pass http://hellonginx;
}
}
关于nginx反向代理的执行流程,可参考:https://blog.csdn.net/qq_36095679/article/details/91358593
访问流程:
  1. 客户端访问地址:http://nginx.test.com/login 或者 http://nginx.test02.com/login
  2. 会被反向代理到:http://127.0.0.1:8080/login 或者 http://127.0.0.1:8081/login 完成跨域
关于nginx反向代理中的负载均衡策略可参考:https://blog.csdn.net/qq_36095679/article/details/89487645
2、配置文件注意点proxy_ pass 指令:该指令用来设置被代理服务器的地址,可以是主机名称、IP地址加端口号等形式 。
其语法结构为: proxy_pass URL;
其中,URL为要设置的被代理服务器的地址,包含传输协议、主机名称或IP地址加端口号、URI等要素 。传输协议通常是“http” 或者“https"。
注意细节:
  1. 如果在配置文件里,我们已经在“upstream”模块定义了“传输协议”,那么在“proxy_pass”就不需要重复定义(二选一即可);
  2. 注意 URL 中是否包含有 URI,Nginx服务器处理的方式是不同的 。见如下例子:
1)proxy_pass对 URI 的处理(重点) #负载均衡:设置代理的服务器列表 可设置多个(目标访问地址)
upstream hellonginx {
server 127.0.0.1:8080;
}
server {
#监听端口80也就是直接访问的URL的端口
listen80;
#设置监听的域名 可设置多个(客户端直接访问的地址)
server_namenginx.test.com;
#反向代理路径(和upstream绑定)
location /api/ {
proxy_pass http://hellonginx;
}
}
配置文件分析:
  1. 客户端访问地址:http://nginx.test.com/api/login
  2. 该请求被配置中显示的location块进行处理,由于proxy_ pass指令的URL变量不含有URI,所以转向的地址为“http://127.0.0.1:8080/api/login”,但我们的目标地址是:http://127.0.0.1:8080/login
新配置文件:
#反向代理路径(和upstream绑定)
location /api/ {
proxy_pass http://hellonginx/myapi/;
}
配置文件分析:
  1. 客户端访问地址:http://nginx.test.com/api/login
  2. nginx转向的地址为“http://127.0.0.1:8080/myapi/login”
总结:在使用 Proxy_pass 指令时,如果不想改变客户端访问地址的 URI,就不要在 Proxy_pass 的 URL 变量中配置 URI。
2)proxy_pass指令的URL变量末尾是否加 “ / ”问题 示例1:location / {
#配置1
proxy_pass http://hellonginx;
#配置2
proxy_pass http://hellonginx/;
}
在该配置中,location 块使用 “/” 作为uri变量的值来匹配不包含URI的请求URL 。由于请求URL中不包含URI,因此配置1和配置2的效果是样的 。比如,客户端的请求URL为“http://nginx.test.com/api/login",其将会location 块匹配成功并进行处理 。不管使用配置1还是配置2,转向的URL都为:“http://127.0.0.1:8080/api/login" 。
示例2:location /api/ {
#配置1
proxy_pass http://hellonginx;
#配置2
proxy_pass http://hellonginx/;
}
在该配置中,location 块使用“/api/"作为uri变量的值来匹配包含URI“/api/" 的请求URL 。这时,使用配置1和配置2的转向结果就不相同了 。使用配置1的时候,proxy_ pass 指令中的URL变量不包含URI, Nginx 服务器将不改变原地址的URI;使用配置2的时候,proxy_ pass 指令中的URL变量包含URI “/”,Nginx服务器会将原地址的URI替换为“/” 。
  1. 比如,客户端的请求URL为“http://nginx.test.com/api/login";
  2. 使用配置1的时候,转向的URL为"http://127.0.0.1:8080/api/login",原地址的URI“/api/" 未被改变;
  3. 但使用配置2时,转向的URL为“http://127.0.0.1:8080/login”,可以看到,原地址的URI“/api/" 被替换为“/" 。
大家在应用过程中,一-定要注意到该指令在配置上的细节问题,分清楚URL和URI的区别与联系,并能够正确使用它们配置出符合需求的Nginx服务器 。
如果我们在实际使用中,希望nginx转发后的地址不包含Location 的 uri (即“/api”),我们有两种方式处理:
  1. 如上,示例2:proxy_pass指令的URL变量末尾加上 “ / ”;
  2. 在proxy_pass指令前添加 Rewrite指令: “rewrite ^/api/(.*)$ /$1 break; ”,proxy_pass的末尾就不用添加“/”;
关于 Rewirte指令的使用,请继续往下阅读 。
3、URL与URI的区别与联系
URI包括URL和URN两个类别,URL是URI的子集,所以URL一定是URI,而URI不一定是URL
URI = Universal Resource Identifier 统一资源标志符,用来标识抽象或物理资源的一个紧凑字符串 。
URL = Universal Resource Locator 统一资源定位符,一种定位资源的主要访问机制的字符串,一个标准的URL必须包括:protocol、host、port、path、parameter、anchor 。
URN = Universal Resource Name 统一资源名称,通过特定命名空间中的唯一名称或ID来标识资源 。
4、Location用法总结 详情请查看博客:https://blog.csdn.net/qq_36095679/article/details/101272135
5、 Rewrite 用法总结 详情请查看博客:https://blog.csdn.net/qq_36095679/article/details/101277202