利用nginx解决跨域问题
前言
最近遇到了跨域问题,结合之前【微信支付开发本地接收异步通知回调】的经验,利用 Nginx 实现了跨域。
公司之前为了解决跨域问题,用的是 iFrame,反正对于只做后端的我而言,觉得很复杂,但是现在利用 nginx 如此简单就实现了跨域,感觉还挺有成就感,哈哈!
为什么会出现跨域问题?
前人已经总结得很好了,就借鉴一下吧!

我们在开发项目中遇到的跨域问题具体是这样的,公司的域名若是 www.domain.com,那么如果是发送的 Ajax 请求就不通过这个域名走了,而是通过 a.domain.com,于是便出现了跨域问题。
比如在 www.domain.com 首页中需要通过 Ajax 获取用户登录信息。
准备工作
下载演示项目
为了演示这个跨域问题,我创建了一个 SpringBoot 项目,便于演示,如果不会 SpringBoot 也没有关系,因为重点在于 Nginx 配置上面。
【点我下载】 提取密码: 8e68
启动演示项目
因为是SpringBoot 项目,因此可以通过 java -jar 的方式直接启动,为了演示跨域,因此需要启动两个项目,这里我们用两个端口来分别启动项目。
## A 项目,端口设置为8080
java -jar -Dserver.port=8080 demo.jar
## B 项目,端口设置为8090
java -jar -Dserver.port=8090 demo.jar
配置本地 Host
为了演示还需要两个域名,不用真正的域名,修改本地的 Host 即可,将两个域名的 Host 都执行本地。可以使用 SwitchHosts 来方便切换。
127.0.0.1 www.domain.com
127.0.0.1 a.domain.com

配置Nginx
编译安装 Nginx后, 修改 nginx.conf 配置文件。
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
keepalive_timeout 65;
#gzip on;
upstream webServer {
server 127.0.0.1:8080;
}
upstream ajaxServer {
server 127.0.0.1:8090;
}
server {
listen 80;
server_name a.domain.com;
location / {
proxy_pass http://ajaxServer;
}
}
server {
listen 80;
server_name www.domain.com;
location / {
proxy_pass http://webServer;
}
}
}
这里来详细解释一下这里的配置,a.domain.com 代理到 ajaxServer,即端口设置为 8090 的 B 项目;
server {
listen 80;
server_name a.domain.com;
location / {
proxy_pass http://ajaxServer;
}
}
再看看 www.domain.com 的配置,反向代理到 webServer , 即端口设置为 8080 的 A 项目。
server {
listen 80;
server_name www.domain.com;
location / {
proxy_pass http://webServer;
}
}
测试
访问项目地址 http://www.domain.com/page, 进入以下页面:

当输入框不输入或者输入的是当前域名 http://www.domain.com 时,可以正常提交,不会遇到跨域问题。
当输入 http://a.domain.com 时,点击按钮进行提交,会出现跨域问题。

修改 Nginx 配置文件
修改 www.domain.com 的配置
server {
listen 80;
server_name www.domain.com;
location /proxy/ {
proxy_set_header Host a.domain.com;
proxy_pass http://ajaxServer/;
}
location / {
proxy_pass http://webServer;
}
}
其中这里这处配置是这篇文章的关键点。意思是 http://www.domain.com/proxy/ 开头的请求将会被反向代理到 B 项目 即 http://a.domain.com 域名,proxy_set_header Host 这一行是必须的。需要注意的是,这两行的域名需要保持一致,且第二行后面必须要有一个 /,至于原因,可以参考这篇文章 proxy_pass后的url加不加/的区别
location /proxy/ {
proxy_set_header Host a.domain.com;
proxy_pass http://ajaxServer/;
}
修改之后保存配置文件,重启 Nginx
./nginx -s reload
再次测试
修改提交 URL 为 http://www.domain.com/proxy

点击按钮进行提交,发现此时没有出现跨域问题。虽然提交的URL 域名是 http://www.domain.com,而请求经过 Nginx 的反向代理之后,实际上提交到了 B 项目,即 http://a.domain.com, 也可以看到 B 项目打印了输出语句 userId: 12,由此便解决了跨域问题。
资源下载
文章涉及的jar文件我打成一个压缩包,可以自己下载尝试一下。
【点我下载】 提取密码: 8e68
利用nginx解决跨域问题的更多相关文章
- 无需CORS,用nginx解决跨域问题,轻松实现低代码开发的前后端分离
近年来,前后端分离已经成为中大型软件项目开发的最佳实践. 在技术层面,前后端分离指在同一个Web系统中,前端服务器和后端服务器采用不同的技术栈,利用标准的WebAPI完成协同工作.这种前后端分离的&q ...
- nginx解决跨域(前后端分离)
Nginx解决跨域问题 后端接口 请求地址 返回数据(json数据) http://127.0.0.1:8080//app Hello World! 前端代码 通过nginx做静态资源服务器访问端口8 ...
- 如何用Nginx解决跨域问题
一. 产生跨域的原因 1.浏览器限制 2.跨域 3.XHR(XMLHttpRequest)请求 二. 解决思路 解决跨域有多重,在这里主要讲用nginx解决跨域 1.JSONP 2.nginx代理 3 ...
- 利用Filter解决跨域请求的问题
1.为什么出现跨域. 很简单的一句解释,A系统中使用ajax调用B系统中的接口,此时就是一个典型的跨域问题,此时浏览器会出现以下错误信息,此处使用的是chrome浏览器. 错误信息如下: jquery ...
- 使用nginx解决跨域问题(flask为例)
背景 我们单位的架构是在api和js之间架构一个中间层(python编写),以实现后端渲染,登录状态判定,跨域转发api等功能.但是这样一个中间会使前端工程师的工作量乘上两倍,原本js可以直接ajax ...
- 前端如何使用proxyTable和nginx解决跨域问题
最近经常遇到跨域的问题,有时候问题虽然解决了,但是还是会有些模棱两可概念不清,于是在网上看了一些教程结合实际使用,做个笔记. 1.跨域原因 浏览器的限制 跨域(协议/域名/端口的不同) XMLHttp ...
- 利用Nginx设置跨域的方式
1.服务端可控,添加响应头 2.服务端不可控.通过Nginx反向代理 3.服务端不可控.通过Nginx反向代理添加响应头 第一种方法.服务端可控时,可以在服务器端添加响应头(前端+后端解决) 浏览器地 ...
- vue项目打包本地后通过nginx解决跨域
前言 有时候我们打包好vue项目让后端人员部署项目时可能会有小插曲,为了不麻烦后端人员和避免尴尬,最好的办法就是在本地自己先测一下,而在本地运行打包后的项目会遇到接口跨域的问题.我平时经常用的方法就是 ...
- Nginx解决跨域问题(CORS)
跨域 解决跨域问题一般有两种思路: CORS 在后端服务器设置 HTTP 响应头,把你需要运行访问的域名加入加入 Access-Control-Allow-Origin中. jsonp 把后端根据请求 ...
随机推荐
- webservice之helloword(web)rs
spring整合webservice 1.pom.xml文件 <dependencies> <!-- cxf 进行rs开发 必须导入 --> <dependency> ...
- Beta阶段第六篇Scrum冲刺博客-Day5
1.站立式会议 提供当天站立式会议照片一张 2.每个人的工作 (有work item 的ID),并将其记录在码云项目管理中: 昨天已完成的工作. 张晨晨:完善收藏功能 郭琪容:收藏功能的实现 吴玲:完 ...
- Hdu1695 GCD 2017-06-27 22:19 30人阅读 评论(0) 收藏
GCD Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- Hdu1010 Tempter of the Bone(DFS+剪枝) 2016-05-06 09:12 432人阅读 评论(0) 收藏
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- security.php
<?php /** * */ class Security { public function csrf_verify() { if(count($_POST) == 0) { return ' ...
- SRM475
250pt: 题意:有最长N=17的一条格子,每个格子是W.B和R三种颜色之一,当某个格子上有兔子时,下一个回合该兔子按照以下的规则移动: 如果兔子在第一个格子,则向右移动一格: 否则如果兔子在倒数两 ...
- android延时弹出软键盘
searchEditView.setFocusable(true); searchEditView.setFocusableInTouchMode(true); searchEditView.requ ...
- 《principal component analysis based cataract grading and classification》学习笔记
Abstract A cataract is lens opacification caused by protein denaturation which leads to a decrease i ...
- NLTK之WordNet 接口【转】
转自:http://www.cnblogs.com/kaituorensheng/p/3149095.html WordNet是面向语义的英语词典,类似于传统字典.它是NLTK语料库的一部分,可以 ...
- 利用阿里大于接口发短信(Delphi版)
阿里大于是阿里通信旗下产品,融合了三大运营商的通信能力,提供包括短信.语音.流量直充.私密专线.店铺手机号等个性化服务.每条四分五,价钱还算公道,经老农测试,响应速度非常快,基本上是秒到.官方文档提供 ...