访问我的博客

前言

最近遇到了跨域问题,结合之前【微信支付开发本地接收异步通知回调】的经验,利用 Nginx 实现了跨域。

公司之前为了解决跨域问题,用的是 iFrame,反正对于只做后端的我而言,觉得很复杂,但是现在利用 nginx 如此简单就实现了跨域,感觉还挺有成就感,哈哈!

为什么会出现跨域问题?

前人已经总结得很好了,就借鉴一下吧!

图片来源地址: http://www.cnblogs.com/gabrielchen/p/5066120.html

我们在开发项目中遇到的跨域问题具体是这样的,公司的域名若是 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解决跨域问题的更多相关文章

  1. 无需CORS,用nginx解决跨域问题,轻松实现低代码开发的前后端分离

    近年来,前后端分离已经成为中大型软件项目开发的最佳实践. 在技术层面,前后端分离指在同一个Web系统中,前端服务器和后端服务器采用不同的技术栈,利用标准的WebAPI完成协同工作.这种前后端分离的&q ...

  2. nginx解决跨域(前后端分离)

    Nginx解决跨域问题 后端接口 请求地址 返回数据(json数据) http://127.0.0.1:8080//app Hello World! 前端代码 通过nginx做静态资源服务器访问端口8 ...

  3. 如何用Nginx解决跨域问题

    一. 产生跨域的原因 1.浏览器限制 2.跨域 3.XHR(XMLHttpRequest)请求 二. 解决思路 解决跨域有多重,在这里主要讲用nginx解决跨域 1.JSONP 2.nginx代理 3 ...

  4. 利用Filter解决跨域请求的问题

    1.为什么出现跨域. 很简单的一句解释,A系统中使用ajax调用B系统中的接口,此时就是一个典型的跨域问题,此时浏览器会出现以下错误信息,此处使用的是chrome浏览器. 错误信息如下: jquery ...

  5. 使用nginx解决跨域问题(flask为例)

    背景 我们单位的架构是在api和js之间架构一个中间层(python编写),以实现后端渲染,登录状态判定,跨域转发api等功能.但是这样一个中间会使前端工程师的工作量乘上两倍,原本js可以直接ajax ...

  6. 前端如何使用proxyTable和nginx解决跨域问题

    最近经常遇到跨域的问题,有时候问题虽然解决了,但是还是会有些模棱两可概念不清,于是在网上看了一些教程结合实际使用,做个笔记. 1.跨域原因 浏览器的限制 跨域(协议/域名/端口的不同) XMLHttp ...

  7. 利用Nginx设置跨域的方式

    1.服务端可控,添加响应头 2.服务端不可控.通过Nginx反向代理 3.服务端不可控.通过Nginx反向代理添加响应头 第一种方法.服务端可控时,可以在服务器端添加响应头(前端+后端解决) 浏览器地 ...

  8. vue项目打包本地后通过nginx解决跨域

    前言 有时候我们打包好vue项目让后端人员部署项目时可能会有小插曲,为了不麻烦后端人员和避免尴尬,最好的办法就是在本地自己先测一下,而在本地运行打包后的项目会遇到接口跨域的问题.我平时经常用的方法就是 ...

  9. Nginx解决跨域问题(CORS)

    跨域 解决跨域问题一般有两种思路: CORS 在后端服务器设置 HTTP 响应头,把你需要运行访问的域名加入加入 Access-Control-Allow-Origin中. jsonp 把后端根据请求 ...

随机推荐

  1. vs和vim

    vs:win+R键 输入DEVENV(DEV代表development,ENV代表environment)可以召唤vs,但是有的时候召唤不出来,是因为你的vs安装在c盘program里也就是默认安装, ...

  2. EL表达式总结

    EL表达式是在JSP中使用的 EL表达式的作用:简化jsp文件中的<% %>. [EL的概述] 什么是EL: 为什么学习EL: * 简化JSP的代码,而且减少<%%> 使用EL ...

  3. Linux 修改默认的 yum 源

    官方的yum源在国内访问效果不佳. 需要改为国内比较好的阿里的 yum源,因为每次装的时候都得百度,所以这里记录一下. 修改方式: 1)cd /etc/yum.repos.d/ 这个目录下普通用户可能 ...

  4. 修改vsftpd的默认根目录

    修改ftp的根目录只要修改/etc/vsftpd/vsftpd.conf文件即可: 加入如下几行: local_root=/var/www/html chroot_local_user=YES ano ...

  5. SWFUpload 在ie9上出现的bug

    SWFUpload 在ie9下会出现js错误 参考以下几个网址,备忘: http://code.google.com/p/swfupload/issues/detail?id=348 http://c ...

  6. Windows远程桌面连接ubuntu 16

    一.安装Xrdp Windows远程桌面使用的是RDP协议,所以ubuntu上就要先安装Xrdp,在ubuntu软件中心搜索xrdp安装. 安装xrdp的同时会自动安装vnc4server,xbase ...

  7. SQL关闭自增长列标识:SET IDENTITY_INSERT

    关闭自增长列添加记录,然后再恢复自增长功能 SET IDENTITY_INSERT 表名 ON; inert ,); SET IDENTITY_INSERT 表名 OFF

  8. wpf Listbox 实现按住ctrl键来取消选中

    1. 首先继承一个listbox,来获得按住ctrl键时,点击的item public class ListBoxEx : ListBox { public BeatTemplateWave GetA ...

  9. .Net中验证码图片生成

    开发网站或平台系统,登录页面是必不可少的功能,但是现在很多人可以使用工具暴力破解网站密码,为了防止这类非法操作,需要在登录页面添加验证,验证码就是最常用的一种验证方式. 我结合了自己的经验和网上的验证 ...

  10. .net下WinDbg使用说明

    加载调试文件 .loadby sos mscorwks #.Net 3.5版本及以下 .loadby sos clr #.Net 4.0 WinDbg的基本命令 !threads #显示所有线程 !d ...