windows环境下 nginx+iis 反向代理解决跨域问题
项目基本完成,是时候花点时间整理一下最近的姿势了
1 什么是跨域?
网上对于跨域的概念会有大篇幅的文章去解释,似乎有点玄乎,初学者很容易对这个概念产生恐惧,跨域其实很简单,其实只要知道一点,无法跨域访问的本质原因其实是浏览器为了安全对前端脚本(一般脚本都是js)请求的一种限制,注意是浏览器的限制,而不是服务器的限制
即同一域下的js只能请求同一域下的接口,何为同一域?何为不同域?端口号相同且请求协议相同且主机名相同即为同一域,三个条件任意一条不满足都是跨域访问
下面实战一个简单的栗子:
如图,我们在本地IIS新建一个端口号为8081的web1,地址为http://localhost:8081,再新建一个端口号为8083的web2,地址为http://localhost:8083

然后在web1放一个代码如下的静态html,用ajax去请求web1下面的接口

web2里面为打包发布的.net webapi,代码如下
public class HomeController : ApiController
{
// GET api/home/get
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
一切就绪后我们http://localhost:8081打开web1,浏览器调试发现会有如下报错

由于端口号不同,XMLHttpruqest对象无法请求http://localhost:8083的数据,这就是端口号不同导致的Ajax无法跨域请求。跨域其实就这么简单
2 那么如何解决跨域问题呢?
网上关跨域问题的解决方案有多种多样,我大概整理了一下大概有这么多跨域解决方案
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域
上述方案前6种方案都有大大小小的问题:
比如方案1中的jsonp实现跨域的缺点:只能实现get一种请求,传输数据有限制。又比如方案6中的CORS跨域虽然支持Post请求,但是必须要所跨域的服务器需要实现Cors,而且还有少量浏览器不兼容,上述8,9两种方案可能是相对比较新的解决方案,我这边也没深入了解学习过,有兴趣的朋友可以自行百度学习一下,在这里主要分享一下关于Nginx的实战总结
3 Nginx反向代理解决跨域问题
什么是反向代理?什么是正向代理?我之前有文章写过这概念,这里就不过多的解释这个概念了,可以参考文章https://www.cnblogs.com/ruanraun/p/agent.html
3.1 ngnix安装配置
首先去官网下载 ngnix http://nginx.org/en/download.html
解压安装包后发现如下目录,不要急着点击nginx.exe

cmd打开命令提示符,cd命令定位到当前目录(还有一种快捷的定位到当前目录的方法:打开到要定位的目录,Shift+鼠标右键 选择此处打开命令提示窗口,不过win10安装了PowerShell的好像就没有这个选项,那就老老实实用命令定位到当前目录了,不要用PowerShell)
定位到上图nginx的目录之后,用start nginx命令启动nginx.exe

然后输入tasklist /fi "imagename eq nginx.exe" 检查程序是否运行成功,如图即为运行成功

如果没有运行成功一般都是80端口被占用,去logs目录下查看日志

两种解决方案:
1,禁用占用80端口的程序,输入命令netstat -ano |more,查看到pid为4的程序占用了改端口,禁用掉这个程序,个人觉得这个方法不太靠谱,因为你可能不知道被禁用程序的作用,有时可能是系统程序,也有可能是部署的其他程序,所以直接禁用可能会引起其他问题,除非非要部署到80端口且知道80端口被占用程序的作用的情况下使用这个解决方案

2,改nginx配置,使用其他端口,打开conf文件下的nginx.conf文件,把里面的80端口改成其他端口,我这里用的是8082端口


修改完配置完成后保存,然后到之前的命令提示符窗口输入:nginx -s reload 重启nginx,记住每次修改完配置后都要重启nginx
然后访问http://localhost:8082,出现下面界面说明就配置OK啦

3,继续配置nginx.conf文件实现跨域

配置说明:
1.由配置信息可知,我们让nginx监听localhost的8082端口,web1与web2的访问都是经过localhost的8082端口进行访问。
2.我们特殊配置了一个“/apis”目录的访问,并且对url执行了重写,最后使以“/apis”开头的地址都转到“http://localhost:8081”进行处理。
3.rewrite ^/apis/(.*)$ /$1 break;
代表重写拦截进来的请求,并且只能对域名后边以“/apis”开头的起作用,例如www.a.com/apis/msg?x=1重写。只对/apis重写。
rewrite后面的参数是一个简单的正则 ^/apis/(.*)$ ,$1代表正则中的第一个(),$2代表第二个()的值,以此类推。
break代表匹配一个之后停止匹配。
全部配置文件如下
#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;
#tcp_nopush on; #keepalive_timeout 0;
keepalive_timeout 65; #gzip on; server {
listen 8082;
server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / {
proxy_pass http://localhost:8081;
proxy_redirect default;
} location /apis { #添加访问目录为/apis的代理配置
rewrite ^/apis/(.*)$ /$1 break;
proxy_pass http://localhost:8083;
} #error_page 404 /404.html; # redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
} # proxy the PHP scripts to Apache listening on 127.0.0.1
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#} # deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
} # another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8082;
# server_name somename alias another.alias; # location / {
# root html;
# index index.html index.htm;
# }
#} # HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost; # ssl_certificate cert.pem;
# ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on; # location / {
# root html;
# index index.html index.htm;
# }
#} }
还有一最后一步就是修改web1下面的静态文件代码,将请求url改成/apis/api/Home/Get

最后重启nginx,访问http://localhost:8082,有时可能会有缓存问题显示之前的欢迎界面用Ctrl+F5刷新一下就好了,如下图:
我们看到http://localhost:8082显示了web1的界面,并且正常输web2接口返回的数据,是不是换了个思维解决了跨域的问题,我们最终访问的地址时间是nginx代理的http://localhost:8082,这也就是所说的反向代理,访问http://localhost:8082的客户端并不知道用户界面实际是放在http://localhost:8081端口的web1下,接口程序放在http://localhost:8083端口的web2下。

4 总结
反向代理不仅仅可以解决跨域问题,还有很多好处,大型项目中前端文件和接口程序完全可以发布到不同的服务器中,使用反向代理技术,前后端各自维护自己的服务器,接口程序还可以供不同平台使用.......
nginx十分强大,大佬们都在使用:中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
windows环境下 nginx+iis 反向代理解决跨域问题的更多相关文章
- nginx反向代理解决跨域问题
跨域:浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域 . 下表格为前后端分离的域名,技术信息: 域名 服务器 使用技术 前端 http://b.yynf.com ...
- 前端通过Nginx反向代理解决跨域问题
在前面写的一篇文章SpringMVC 跨域,我们探讨了什么是跨域问题以及SpringMVC怎么解决跨域问题,解决方式主要有如下三种方式: JSONP CORS WebSocket 可是这几种方式都是基 ...
- nginx反向代理解决跨域问题,使本地调试更方便
我们可能都会遇到一个这样的问题,线上环境是https://...,本地启动了项目,域名是localhost:8000等,本地想要访问线上的接口,直接在本地调试,却提示跨域,这个时候我们可以配置ngin ...
- 利用nginx 反向代理解决跨域问题
说到nginx,不得不说真的很强大,也带来很多便利用于解决一些头疼的难题. 一般来说可以用来做:静态页面的服务器.静态文件缓存服务器.网站反向代理.负载均衡服务器等等,而且实现这一切,基本只需要改改那 ...
- Nginx 反向代理解决跨域问题分析
当你遇到跨域问题,不要立刻就选择复制去尝试.请详细看完这篇文章再处理 .我相信它能帮到你. 分析前准备: 前端网站地址:http://localhost:8080 服务端网址:http://local ...
- nginx反向代理解决跨域
nginx作为反向代理服务器,就是把http请求转发到另一个或者一些服务器上.通过把本地一个url前缀映射到要跨域访问的web服务器上,就可以实现跨域访问.对于浏览器来说,访问的就是同源服务器上的一个 ...
- wamp2.4.4 如何配置虚拟主机及反向代理(解决跨域问题)
一.找到安装目录下的httpd.conf文件 1. 删除Include conf/extra/httpd-vhosts.conf前面的#号(开启虚拟主机的配置) 2. 删除LoadModule pro ...
- vue反向代理解决跨域
问题描述 在项目开发的时候,接口联调的时候一般都是同域名下,且不存在跨域的情况下进行接口联调,但是当我们现在使用vue-cli进行项目打包的时候,我们在本地启动服务器后,比如本地开发服务下是 http ...
- webpack-dev-server 设置反向代理解决跨域问题
一.设置代理的原因 现在对前端开发的要求越来越高,并且随着自动化以及模块化的 诞生,前后端开发模式越来越流行.后端只负责接口,前端负责数据展示.逻辑处理.但是前后端开发模式,有一个重要的问题,就是跨域 ...
随机推荐
- tomcat之日志切割
日志分割 场景:日志量比较大,且研发程序没有设置分卷 1.配置样例: 文件路径:/etc/logrotate.d/tomcat /data/logs/catalina.out { daily comp ...
- 使用Unicode字符实现换行
要让inline元素换行可以使用Unicode字符实现: <!DOCTYPE html> <html lang="en"> <head> < ...
- 一篇你看了就懂的DNS详解
DNS(Domain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住IP. 通过域名,最终得到该域名对应的IP地址 ...
- es6学习笔记2-—symbol、变量与作用域
1.新的字符串特性 标签模板: String.raw(callSite, ...substitutions) : string 用于获取“原始”字符串内容的模板标签(反斜杠不再是转义字符): > ...
- [转]腾讯云Linux云服务器文件上传利器——WinSCP
本文转自:http://bbs.qcloud.com/thread-4379-1-1.html WinSCP简介 WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端.同时支持S ...
- Visual Studio 监视与快速监视即时窗口没有智能提示
工具->选项->文本编辑器->C# 将 自动列出成员 参数信息 都勾选上
- Java使用递归的方法进行冒泡排序
对于递归来说,我只了解它的概念,没有具体使用过,近期也是尝试着用递归写了一下冒泡排序和大家分享,希望能帮助大家了解递归 递归是什么?通俗的讲:在方法内部调用自己 花了几分钟整出来的,下面是递归冒泡排序 ...
- C++ auto 关键字的使用
C++98 auto 早在C++98标准中就存在了auto关键字,那时的auto用于声明变量为自动变量,自动变量意为拥有自动的生命期,这是多余的,因为就算不使用auto声明,变量依旧拥有自动的生命期: ...
- Python traceback 异常处理
刚接触Python的时候,简单的异常处理已经可以帮助我们解决大多数问题,但是随着逐渐地深入,我们会发现有很多情况下简单的异常处理已经无法解决问题了,如下代码,单纯的打印异常所能提供的信息会非常有限. ...
- layui 页面加载 阴影 请求页面加载转圈页面
var layerIndex= layer.load(1,{shade: [0.3, '#000']}); $.post('${pageContext.request.contextPath}/lea ...