内容简介:https://www.zhihu.com/question/26379635虚拟主机:多个域名指向同一个服务器,服务器根据不同域名,将请求转向不同应用服务器,看上去好像有多个主机,实际上只有一个主机。
首先,浏览器为何要采用同源策略对跨域请求进行限制? 可参照知乎链接:
https://www.zhihu.com/question/26379635
其次,常用解决方案:
被调用方 - NGINX解决方案
虚拟主机:多个域名指向同一个服务器,服务器根据不同域名,将请求转向不同应用服务器,看上去好像有多个主机,实际上只有一个主机。
先进行被调用方虚拟主机的配置:
先进行host的配置:
打开windows下的hosts文件,编辑,先映射一个本地域名:
127.0.0.1 b.com复制代码
用b.com表示被调用方的域名。
然后打开nginx下的conf目录,新建vhost文件夹,用于存放虚拟主机的配置文件,实际工作中一般就采用这种习惯;打开nginx.conf文件,在最后一行添加代码
include vhost/*.conf;复制代码
要nginx载入这个目录下面所有.conf结尾的文件。
在vhost中新建b.com.conf文件,用nginx的语法在其中增加一节点:
作用是,将所有请求转到localhost:8080,监听80端口,命名为b.com。
在nginx-1.11.5目录下打开命令行窗口:
先运行 nginx.exe -t ,测试一下配置文件,测试成功后运行 start nginx.exe 启动nginx,启动成功后进行测试:
将原来的访问url开头的localhost:8080改为b.com,运行后若依然能正常访问,代表测试成功,说明虚拟主机配置完成了。
因为这次是要在nginx上实现filter的功能,则先将原来的后台服务端的filter功能删除掉,
将注册filter的配置注释掉:
将下面的逻辑移到nginx中:
其中3个为固定值,另外两个由请求的头来决定,
改为:
将预检命令的逻辑处理也添加其中,在nginx中直接返回,就不需要转到应用服务器了。
运行 nginx.exe -t ,测试一下配置文件。
运行 nginx.exe -s reload 对nginx进行重新载入。
原来html中base url是通过localhost:8080直接访问的被调用方的应用服务器,现在将localhost:8080改为b.com,即变成了html中去访问被调用方的nginx http服务器了。
发送的cookie是被调用方的域名的cookie。在b.com下添加 document.cookie='cookie1=xxx' 。
被调用方 - apache解决方案
先运行 nginx.exe -s stop 将nginx停止掉,然后刷新b.com的请求,请求失败,说明nginx被停掉了。接下来进行apache的配置:
与nginx一样,我们先进行虚拟主机的配置,进入Apache24/conf目录下,打开httpd.conf文件,
先打开虚拟主机的相关配置,搜索vhost,将 LoadModule...mod_vhost_alias.so 注释打开,
将配置文件 Include conf/extra/httpd-vhosts.conf 注释也打开,保存httpd.conf。
找到对应的虚拟主机配置文件,即 conf/extra/httpd-vhosts.conf ,打开,文件中的每一个节点就是一个虚拟主机,将最后一个节点的代码复制一份并添加到最后,删掉无用的前两行,ServerName改为b.com,日志改为 b.com-error.log... 。在最后一行增加一个代理,让它把我们的请求转发过去,
ProxyPass / http://localhost:8080/
然后将此配置文件保存。因为此处使用了Proxy模块,所以需将文件中Proxy模块也打开,搜一下,将140行
LoadModule proxy_module modules/mod_proxy.so复制代码
打开,还需要把149行的
LoadModule proxy_http_module modules/mod_proxy_http.so复制代码
打开,保存文件。
键入Apache/bin目录,双击httpd.exe,弹出窗口,Apache启动成功,刷新下b.com的请求,此时b.com可正常访问了,表示虚拟主机配置成功了。
来测试一下,刷新下测试用例,看到为全部失败,接下来需要在Apache上配置下响应头,
增加支持跨域的响应头:
继续编辑httpd-vhosts.conf文件,在ProxyPass下增加代码:
Apache的配置比较复杂:
需要将httpd.conf中Headers和Rewrite模块打开:
搜索headers,将118行打开
LoadModule headers_module modules/mod_headers.so复制代码
搜索rewrite,将158行打开
LoadModule rewrite_module modules/mod_rewrite.so复制代码
保存修改后的两个文件。
将Apache关掉,双击重启,刷新测试用例,此时测试用例全部成功,表示此时的Apache支持跨域了,Apache的配置到此结束。
被调用方 - Spring框架解决方案
之前的方案都和框架无关,比如filter,是每个web应用都有的。如果采用了Spring框架,那么解决方案就变得简单起来,增加相应注解即可,请求也不需要再经过中间的http服务器了。
所以,首先将html中的base url b.com改回为localhost:8080,修改服务器后台代码,在TestController中增加注解,
@CrossOrogin
public class TestController {
复制代码
保存,
再次刷新测试用例,可以看到,测试用例全部通过。
@CrossOrogin 可以加在类上面,也可以加在具体的方法上面。加在类上即代表此类的所有方法都支持跨域;它还可以进行一些额外的配置,但一般场景是不需要额外配置的。
调用方解决跨域 - 隐藏跨域 - nginx配置
当你无法修改被调用方的时候,就要在调用方做文章。请求是经由调用方的http服务器的反向代理,转发到被调用方的服务器的,在浏览器上面,看不到任何的跨域请求。
那么,什么是反向代理呢?
简单来说,就是你访问同一个域名的两个不同url,它们最后会去到两个不同的服务器,我们通过接下来的测试来理解这个概念:
先看一下反向代理在nginx上是怎样配置的:
配置之前,先把测试环境还原成不支持跨域调用,
把注解 @CrossOrigin 删除掉:
接下来,在
C:\Windows\System32\drivers\etc\hosts 文件中增加一个host,
将原127.0.0.1 b.com改为
127.0.0.1 b.com a.com复制代码
用a.com表示调用方的虚拟主机。
然后,在nginx-1.11.5\conf\vhost中新建配置文件a.com.conf
域名为a.com,将所有请求转发到81端口,
加一个代理,把我们要调用的服务器的地址代理成 ajaxserver
将html中的base url改为 /ajaxserver 。
运行 start nginx.exe 启动nginx
运行 nginx -s reload 重新加载配置,访问a.com,可以看到3个成功,但getCookie失败了,
是因为新的域名里没有cookie的信息,在a.com下添加 document.cookie="cookie1=xxx"
再次刷新,测试用例全部成功,跨域问题得到了解决。
看一下这种隐藏跨域与之前的支持跨域最大不同是什么?
就是我们调用的base url。
隐藏跨域下面调用的url都是本域的,所以base url处为相对地址,
而之前支持跨域里面,base url处写的必须是绝对地址,这就是最大的不同。
浏览器看到都是相对地址,都是同一个域的地址,所以不会有任何跨域问题。
调用方解决跨域 - 隐藏跨域 - Apache配置
Apache反向代理配置:
配置的目的就是增加一个虚拟主机,在虚拟主机中把跨域请求做一个代理,
找到Apache的虚拟主机配置文件conf/extra/httpd-vhosts.conf
增加一个节点:
将base url改为 ajaxserverapache ,
保存。将 nginx.exe -s stop 停掉,启动Apache服务,
运行a.com,测试成功,
且发现Request URL为http://a.com/ajaxserverapache/getCookie
Apache反向代理配置完成。
注:以上文章整理自慕课网教学视频:
https://www.imooc.com/video/16591
https://www.imooc.com/video/16592
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Fluent Python
Luciano Ramalho / O'Reilly Media / 2015-8-20 / USD 39.99
Learn how to write idiomatic, effective Python code by leveraging its best features. Python's simplicity quickly lets you become productive with it, but this often means you aren’t using everything th......一起来看看 《Fluent Python》 这本书的介绍吧!