在现代开发模式中,前后端完全分离,前后端为两个不同的项目,在项目发布之后才将前后端项目合并,或者不合并,后端仅仅是一个apiserver,提供一套接口供移动端和web端调用。但是由于浏览器的安全策略的限制,ajax不能调用不同源的接口或者资源。虽然跨域的解决方案有很多种,但是最直接,不需要修改代码的方法是使用nginx反向代理,其配置如下:
在nginx的nginx.conf 文件的http配置块里加上下面配置
server {
listen 8090;
server_name myServer;
charset utf-8;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers Origin,X-Requested-Width,Content-Type,Accept;
location / {
proxy_pass http://localhost:8080/api/;
}
}
location / {
proxy_pass http://localhost:8080/api/;
}
只要访问localhost:80就自动映射到http:localhost:8080/api/这个网络路径下。
由于跨域的请求response header没有Access-Control-Allow-Origin这个字段浏览器才会限制访问,所以要在这里加上
add_header Access-Control-Allow-Origin *; //标示可以跨任何域调用
这时候跨域get没有问题了, 但是post请求的response中有content-type等其他字段,浏览器会报类似的错误:
Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response
所以要在nginx上添加允许的字段:
add_header Access-Control-Allow-Headers Origin,X-Requested-Width,Content-Type,Accept;
这个时候可以放肆的调用跨域接口了,哈哈哈!
其实我用跨域请求后端接口,是因为我前端使用的是angular2来开发,而使用ng-cli管理前端项目,ng-cli本身自带了一个http服务,而且支持热编译,热刷新。所以在开发阶段不想把前后端项目合并调试,而且那样的做法也不是很经济,所以我才有了跨域调接口的方法。但是,项目发布的时候还是要将前后端项目合并发布。
然而很戏剧的是,当我配置好了nginx反向代理,测试能够正常的跨域之后,我回头来写这篇博文的过程中,竟然发现了一个神器-chrome插件Allow-Control-Allow-Origin:*
这个插件支持所有的跨域调用,而代码和服务器不需要做任何的修改和配置,也不需要做任何代理。非常适合与那种开发阶段前后端分离,发布时将前后端合并的场景,也就是我目前的场景。哈哈哈,虽然绕了一大圈,但是值得,万一以后遇到前后端项目分离发布的场景呢。