服务器配置正反向代理解决跨域请求问题
web浏览器请求时存在跨域问题,解决时一般有两种方式:
一、程序文件用JSONP请求,这种方式是在请求中添加<srcipt>头,只支持GET方式,对POST请求不支持。
二、配置服务器,对服务器Tengine、haproxy、nginx、apache、IIS等设置proxy正反向代码。
正向代理:(代理服务器)代理客户端请求,服务器端只知道和代理服务器有通信,不知道客户端,多用于代理翻墙访问(现在多用VPN翻墙)。
反向代理:(代理服务器)代理服务器请求,客户端只知道和代理服务器有通信,不知道服务器端,多用于网站的负载均衡与跨域问题处理。
反向代理的优势:
.请求的统一控制,包括设置权限、过滤规则等
.区分动态和静态可缓存内容
.隐藏内部服务真实地址,暴露在外的只是反向代理服务器地址
.实现负载均衡,内部可以采用多台服务器来组成服务器集群,外部还是可以采用一个地址访问
.解决Ajax跨域问题
.作为真实服务器的缓冲,解决瞬间负载量大的问题
1、Apache反向代理
修改Apache的配置文件httpd.conf,去掉以下两行前面#号,从而启用Apache proxy module
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so
找到域名httpd-vhosts.conf配置文件,在virtualHost里面配置反向代理,完成之后的配置代码如下:
<VirtualHost *:80> #反向代理设置 ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPass /project http://ip_address/project ProxyPassReverse /project http://ip_address/project </VirtualHost>
ProxyRequests Off 指令是指采用反向(reverse)代理,On为正向代理。
ProxyPass用于将一个远程服务器映射到本地服务器的URL空间中。
而ProxyPassReverse主要解决后端服务器重定向造成的绕过反向代理的问题,在后端服务器会进行服务器端跳转时使用,对HTTP重定向时回应中的Location、Content-Location和URI头里的URL进行调整
如果不想对某个子目录进行反向代理时,可以用"!"指令。比如说:
ProxyPass /folder/exception ! ProxyPass /folder http://****.com/floder将会代理除 /folder/exception 之外的所有对 http://****.com/floder 的请求。
配置完成之后,访问 http://localhost/project 实际就是访问 http://ip_address/project 上的资源。简单的说,我们通过这个配置欺骗了js,让js以为我们一直在相同域名下访问资源。
重启Apache,重命名之前本地的后端代码文件夹(反正让本地后端代码不能够正常运行即可),然后测试一下看api数据读取是否正常。若api数据读取正常,那么Apache反向代理设置成功并且正常工作。
也可以用 URL 重写的方法来实现
1 修改 apache 配置文件 httpd.conf ,去掉以下三行前面 # 号
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule rewrite_module modules/mod_rewrite.so2 在 server config 或 virtual host 中增加:
<Location /folder> SetHandler proxy-server order allow,deny Allow from all </Location>
RewriteEngine on RewriteRule ^/folder/(.*)$ http://****.com/floder [L,R=301,P,NC]
注释:
Location 指令提供了基于URL的访问控制,对于本域下的 /folder 目录下的任何资源的访问都会首先由proxy-server这个 handler(mod_proxy模块内部定义的一个 handler)来处理。
SetHandler proxy-server 指令是强制所有匹配的文件被一个代理服务器处理。
RewriteEngine on 指令是指打开重写引擎。
RewriteRule 指令是重写规则。
last|L 这个标记用于阻止当前已被重写的 URL 被后继规则再次重写。
redirect|R [=code] 若Substitution以http://thishost[:thisport]/(使新的URL成为一个URI)开头,可以强制性执行一个外部重定向,是跨域或定向到外部域的必备良药。默认为 HTTP 响应码为 302, 我通常指定为301。
proxy|P 此标记使替换成分被内部地强制作为代理请求发送,表明该 rewrite 是通过 mod_proxy 代理过去,而不是通过外部重定向过去。
nocase|NC 忽略大小写,也就是在Pattern与当前 URL 匹配时,’A-Z’和’a-z’没有区别。
2、Nginx代理设置
# 反向代理设置
location /api { proxy_pass "http://ip_address/"; proxy_set_header Host "http://ip_address/"; proxy_set_header X-Forwarded-For $remote_addr; }proxy_set_header 是向反向代理的后端 Web 服务器请求时,添加制定的header头信息。当请求的后端 Web 服务器有多个基于域名的虚拟主机时,要通过添加指定的 Host 来区分。
在请求和响应头中添加 X-Forwarded-For 原始请求的地址,因为使用了反向代理之后,后端 Web 服务器(以PHP为例)就不能通过 $_SERVER["REMOTE_ADDR"] 变量来获取用户真实的 IP 了。
此时 $_SERVER["REMOTE_ADDR"] 指向的是反向代理的 Nginx 服务器 IP ,通过 $_SERVER["X-Forwarded-For"] 来获取