Apache反向代理处理js跨域问题

  • 发布时间:2017年9月15日 12:12
  • 作者:杨仕航

最近用tastypie和angularjs开发网站。tastypie写后端restful风格的api,angularjs写前端,实现前后端分离。前后端分离开发效率很高,让后端人员专注写后端代码,前端人员专注写前端代码。


在开发阶段,前后端对接就出现跨域问题。

后端用python manage.py runserver开启服务,访问地址为 http://localhost:8000。

前端用pycharm自带测试服务,访问地址为 http://localhost:8369。


两个地址的端口不一样,使用angularjs代码访问后端api接口出现跨域问题,不允许访问api接口。我简单使用chrome浏览器参数允许跨域。可自行搜索一下,用快捷方式或命令行打开chrome浏览器,如下命令:

  1. "C:\Program Files\Google\Chrome\Application\chrome.exe"
  2.   --disable-web-security
  3.   --user-data-dir=F:\chrome_data


其中,注意使用自己电脑上chrome.exe具体地址和--user-data-dir指向的目录要先创建。该文件夹用于保存数据。


但部署到生产服务器就不能使用该方法。

我一开始打算用api.xxx.com访问后端api接口,www.xxx.com访问前端页面。再使用设置header头的方式处理跨域问题。但有两个问题:不是所有浏览器都支持和无法提交cookies给api接口。


仔细研读文档和查阅资料,发现可以使用反向代理的方式解决跨域问题。跨域是因为前后端访问地址不同导致,若我们将前后端访问地址变成一致的,则没有跨域问题。

反向代理可以隐藏服务器真实地址,将我们访问的地址转到我们希望的地址。例如前端部署的地址还是www.xxx.com,后端api接口部署的地址是api.xxx.com。我们可以创建www.xxx.com/api/地址,令其指向到api.xxx.com。如此一来,前后端的域名都是www.xxx.com,则无跨域问题。


具体apache配置如下:

  1. # 前端部署
  2. <VirtualHost *:80>
  3.     ServerName www.xxx.com
  4.     ServerAlias xxx.com
  5.     DocumentRoot /src/angular-js
  6.  
  7.     # angular-js static files
  8.     <Directory /src/angular-js>
  9.         Options -MultiViews +FollowSymLinks
  10.         Require all granted
  11.     </Directory>
  12.  
  13.     # Reverse Proxy
  14.     # 关闭正向代理,才可以使用ProxyPass
  15.     ProxyRequests Off
  16.     # 代理api地址
  17.     ProxyPass /api/ http://api.xxx.com/
  18.     # 不跳转url(不重定向)
  19.     ProxyPassReverse /api/ http://api.xxx.com/
  20.     # 把www的cookies改成api的
  21.     ProxyPassReverseCookieDomain api.xxx.com www.xxx.com
  22.     ProxyPassReverseCookiePath / /api/
  23. </VirtualHost>
  24.  
  25. # 后端部署(用Passenger部署django,可借鉴)
  26. <VirtualHost *:80>
  27.     ServerName api.xxx.com
  28.  
  29.     # Tell Apache and Passenger where your app's code directory is
  30.     DocumentRoot /src/myProject
  31.     PassengerAppRoot /src/myProject
  32.  
  33.     # Tell Passenger that your app is a Python app 
  34.     PassengerAppType wsgi
  35.     PassengerStartupFile wsgi.py
  36.     PassengerPython /usr/bin/python3
  37.  
  38.     # Relax Apache security settings
  39.     <Directory /src/myProject>
  40.       Allow from all
  41.       Options -MultiViews +FollowSymLinks
  42.       Require all granted
  43.     </Directory>
  44. </VirtualHost>


具体配置说明可以查看apache官方文档:

http://httpd.apache.org/docs/2.4/mod/mod_proxy.html

http://httpd.apache.org/docs/2.0/mod/mod_proxy.html

我使用2.4版本,上面实例代码是2.4的。需要启动proxy,指向如下命令:

  1. sudo a2enmod proxy


若是2.2版本,要载入mod_proxy和mod_proxy_http。

  1. LoadModule proxy_module modules/mod_proxy.so
  2. LoadModule proxy_http_module modules/mod_proxy_http.so


前后端部署分别写了两个VirtualHost。反向代理写在www.xxx.com中。我解释那几条配置。

1、"ProxyRequests Off" 是关闭正向代理,使用反向代理。apache代理有正向和反向两种。

2、"ProxyPass /api/ http://api.xxx.com/"  是代理/api/地址,指向http://api.xxx.com/。若我们访问http://www.xxx.com/api/,实际访问http://api.xxx.com/;访问http://www.xxx.com/api/v1/,实际访问http://api.xxx.com/v1/。

3、"ProxyPassReverse /api/ http://api.xxx.com/" ProxyPassReverse要和ProxyPass配套出现,配置和ProxyPass一样,为了不重定向跳转。

4、"ProxyPassReverseCookieDomain api.xxx.com www.xxx.com" 把www.xxx.com的cookies改成api的,让api.xxx.com可以使用cookies。

5、"ProxyPassReverseCookiePath / /api/" 为了让api.xxx.com的cookies可以给www.xxx.com使用。api.xxx.com写入cookies的路径是/,返回给前端需要将路径改成www.xxx.com/api/,即/api/。


当然,apache反向代理有很多配置。具体可以查看官方文档。


上一篇:Django查询对比其他字段

下一篇:tastypie自定义链接使用obj_create方法

评论列表

智慧如你,不想发表一下意见吗?

新的评论

清空

公告 & 打赏

>>

欢迎打赏支持我 ^_^

最新公告

我把服务器搬到国内了,并做了一些优化,速度爆快

2021-09-22

了解更多