在前面写的一篇文章SpringMVC解决跨域问题,我们探讨了什么是跨域问题以及SpringMVC怎么解决跨域问题,解决方式主要有如下三种方式:

JSONP

CORS

WebSocket

可是这几种方式都是基于服务器配置的,即对于自己的网站是可以通过这几种方式解决的,可是现在遇到另一个需求(前面提到过,写扇贝插件,我们不能更改扇贝的服务器配置,也不能发短信叫他们给我配置一下)。

本文探讨了前端如何通过Nginx反向代理的方式解决跨域问题。

跨域

再次重申: 跨域是浏览器行为,不是服务器行为。

实际上,请求已经到达服务器了,只不过在回来的时候被浏览器限制了。就像Python他可以进行抓取数据一样,不经过浏览器而发起请求是可以得到数据,想到通过Nginx的反向代理来解决跨域问题。

代理

所谓代理就是在我们和真实的服务器之间有一台代理服务器,我们所有的请求都是通过它来进行转接的。

正向代理

正向代理就是我们访问不了Google,但是我在国外有一台vps,它可以访问Google,我访问它,叫它访问Google后,把数据传给我。

如图:

反向代理

大家都有过这样的经历,拨打10086客服电话,可能一个地区的10086客服有几个或者几十个,你永远都不需要关心在电话那头的是哪一个,叫什么,男的,还是女的,漂亮的还是帅气的,你都不关心,你关心的是你的问题能不能得到专业的解答,你只需要拨通了10086的总机号码,电话那头总会有人会回答你,只是有时慢有时快而已。那么这里的10086总机号码就是我们说的反向代理。客户不知道真正提供服务人的是谁。

反向代理隐藏了真实的服务端,当我们请求 www.baidu.com 的时候,就像拨打10086一样,背后可能有成千上万台服务器为我们服务,但具体是哪一台,你不知道,也不需要知道,你只需要知道反向代理服务器是谁就好了,www.baidu.com 就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到真实的服务器那里去。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。

如图:

总结

正向代理隐藏了真实的客户端。

反向代理隐藏了真实的服务器。

Nginx 就是一个很好的反向代理服务器,当然apache也可以实现此功能。

windows下Apache配置参考这篇文章: Windows Apache服务器配置

Nginx

Nginx(发音同engine x)是一个 Web服务器,也可以用作反向代理,负载平衡器和 HTTP缓存。该软件由 Igor Sysoev 创建,并于2004年首次公开发布。同名公司成立于2011年,以提供支持。

我在Windows下实现Nginx负载均衡提到过Windows下Nginx命令使用。

Nginx 反向代理模块 proxy_pass

proxy_pass 后面跟着一个 URL,用来将请求反向代理到 URL 参数指定的服务器上。例如我们上面例子中的 proxy_pass https://api.shanbay.com,则将匹配的请求反向代理到 https://api.shanbay.com。

通过在配置文件中增加proxy_pass 你的服务器ip,例如这里的扇贝服务器地址,就可以完成反向代理。

server {

listen 80;

server_name localhost;

## 用户访问 localhost,则反向代理到https://api.shanbay.com

location / {

root html;

index index.html index.htm;

proxy_pass https://api.shanbay.com;

}

}

配置html以文件方式打开

一般的情况下,我们的HTML文件时放置在Nginx服务器上面的,即通过输入 http://localhost/index.html ,但是在前端进行调试的时候,我们可能是通过 使用 file:///E:/nginx/html/index.html 来打开HTML。服务器打开不是特别方便。

而我们之所以要部署在服务器上,是想要使用浏览器自带的CORS头来解决跨域问题,如果不想把HTML放置在Nginx中,而想通过本地打开的方式来调试HTML,可以通过自己添加Access-Control-Allow-Origin等http头,但是我们的AJAX请求一定要加上http://127.0.0.1/request,而不能直接是 /request,于是将nginx.conf作如下配置:

location / {

root html;

index index.html index.htm;

# 配置html以文件方式打开

if ($request_method = 'POST') {

add_header 'Access-Control-Allow-Origin' *;

add_header 'Access-Control-Allow-Credentials' 'true';

add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

}

if ($request_method = 'GET') {

add_header 'Access-Control-Allow-Origin' *;

add_header 'Access-Control-Allow-Credentials' 'true';

add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

}

# 代理到8080端口

proxy_pass http://127.0.0.1:8080;

}

处理DELETE和PUT跨域请求

而现在我的后台是restful风格的接口,采用了delete和put方法,而上面的配置就无能为力了。

可以通过增加对非简单请求的判断来解决DELETE和PUT跨域请求。

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。

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

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

因此,为了使Nginx可以处理delete等非简单请求,Nginx需要作出相应的改变,更改配置如下

location / {

# 完成浏览器的"预检"请求

if ($request_method = 'OPTIONS') {

add_header Access-Control-Allow-Origin *;

add_header Access-Control-Allow-Credentials true;

add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';

add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

return 204;

}

# 配置html在本地打开

if ($request_method = 'POST') {

add_header 'Access-Control-Allow-Origin' *;

add_header 'Access-Control-Allow-Credentials' 'true';

add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

}

if ($request_method = 'GET') {

add_header 'Access-Control-Allow-Origin' *;

add_header 'Access-Control-Allow-Credentials' 'true';

add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

}

root html;

index index.html index.htm;

# 配置html在Nginx中打开

location ~* \.(html|htm)$ {

}

# 代理到8080端口

proxy_pass http://127.0.0.1:8080;

}

我们还必须把我们的html代码放在Nginx中html文件夹内,即使用Nginx当做我们的前端服务器。

URL重写

有时候我们仅仅只想将/api下的url反向代理到后端,可以通过在nginx.conf中配置url重写规则如下:

location / {

root html;

index index.html index.htm;

location ^~ /api {

rewrite ^/api/(.*)$ /$1 break;

proxy_pass https://api.shanbay.com/;

}

}

这样的话,我们只用处理/api下的url。

在配置文件中我们通过rewrite将URL重写为真正要请求的URL,通过proxy_pass代理到真实的服务器IP或者域名。

Cookie

如果Cookie的域名部分与当前页面的域名不匹配就无法写入。所以如果请求 www.a.com ,服务器 proxy_pass 到 www.b.com 域名,然后 www.b.com 输出 domian=b.com 的 Cookie,前端的页面依然停留在 www.a.com 上,于是浏览器就无法将 Cookie 写入。

可在nginx反向代理中设置:

location / {

# 页面地址是a.com,但是要用b.com的cookie

proxy_cookie_domain b.com a.com; #注意别写错位置了 proxy_cookie_path / /;

proxy_pass http://b.com;

}

总结

Nginx解决跨域问题通过Nginx反向代理将对真实服务器的请求转移到本机服务器来避免浏览器的"同源策略限制"。

参考文档:

nginx解决浏览器跨域问题_前端通过Nginx反向代理解决跨域问题相关推荐

  1. 通过nginx反向代理解决跨域

    先写一个发送跨域请求的页面index.html <html> <head><title></title> </head> <body& ...

  2. vue反向代理解决跨域及部署nginx端口转发解决跨域

    1. 前言 本文是为了解决vue反向代理解决跨域及部署服务器nginx端口转发解决跨域,因为踩了不少的坑,百度了很多,也试了太多的方法,最终得以解决,所以记录一下,希望遇到同样问题的友友们可以高效的解 ...

  3. 使用webpack-dev-server设置反向代理解决前端跨域问题

    使用webpack-dev-server设置反向代理解决前端跨域问题 参考文章: (1)使用webpack-dev-server设置反向代理解决前端跨域问题 (2)https://www.cnblog ...

  4. 利用nginx 反向代理解决跨域问题

    利用nginx 反向代理解决跨域问题 参考文章: (1)利用nginx 反向代理解决跨域问题 (2)https://www.cnblogs.com/hpx2020/p/9928175.html 备忘一 ...

  5. nginx反向代理解决跨域问题,使本地调试更方便

    nginx反向代理解决跨域问题,使本地调试更方便 参考文章: (1)nginx反向代理解决跨域问题,使本地调试更方便 (2)https://www.cnblogs.com/gwf93/p/102951 ...

  6. 使用nginx反向代理发起跨域请求

    任务5:http://www.jnshu.com/task/2/45/detail//#1 页面文件放在github:https://github.com/Resalee/css_task/tree/ ...

  7. iconfont配置nginx跨域问题、nginx反向代理接口跨域

    1.nginx配置解决iconfont跨域 浏览器跨域访问js.css.img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在ngin ...

  8. 使用反向代理解决跨域问题

    在项目根目录下新建一个webpack的配置文件:vue.config.js. 跨域问题的解决必须在vue.config.js文件中进行配置书写. 代码内容如下 module.exports={devS ...

  9. webpack-dev-server 设置反向代理解决跨域问题

    webpack-dev-server 设置反向代理解决跨域问题 参考文章: (1)webpack-dev-server 设置反向代理解决跨域问题 (2)https://www.cnblogs.com/ ...

最新文章

  1. 图解 Attention(完整版)!
  2. Leetcode | Binary Tree Maximum Path Sum
  3. Git安装以及操作过程
  4. python3安装venv虚拟环境
  5. 10种可提升Android应用程序运行效果的技巧
  6. 继承Javadoc方法注释
  7. java timer schedule_java怎么再次设置Timer的schedule???
  8. 找出一个字符串中出现次数最多的字_海量数据中找出前k大数(topk问题)
  9. python 枚举类型
  10. 收货详细假地址大全_【肖博数学】考生必看:高中数学三角函数公式大全(史上最全)...
  11. 教育行业oa软件怎么样?
  12. 这7个web前端开发写代码软件,你过用几个?
  13. Sql Server 2008R2 备份文件还原数据库
  14. MATLAB信号处理——信号与系统的分析基础(4)
  15. 西北工业大学电工学mooc第六章测试题及解析
  16. ubuntu12.04双屏拼接
  17. QQ空间g_tk、bkn加密参数算法
  18. 【Flask项目】项目准备之-容联云短信服务平台使用—发送短信、Flask-limiter限流
  19. 刘华:戏说Docker和K8s,一文让你成为懂王
  20. PPG裸奔背后的玄机和迷雾

热门文章

  1. 程序员面试金典 - 面试题 17.07. 婴儿名字(并查集)
  2. nrf52832芯片手册_nRF52832低功耗问题不完全总结
  3. linux用命令行进行无线连接,linux以命令行下配置连接wlan无线网卡
  4. html背景图不显示_批量显示多张有序排列的图标,使用精灵图CSS Sprites这种办法...
  5. 电商网站(Django框架)—— 大纲内容与基本功能分析
  6. 变压器绕组降低邻近效应_了解高频变压器设计基础(2)
  7. java 调用js 解析yml_nodejs库yaml读取yml或yaml配置文件
  8. 论文浅尝 - ICML2020 | 通过关系图上的贝叶斯元学习进行少样本关系提取
  9. 数学家、中科院院士张景中:数学实力影响国家实力是近代以来的共识
  10. 基于深度强化学习的区域化视觉导航方法​​