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浏览器,如下命令:

"C:\Program Files\Google\Chrome\Application\chrome.exe"
  --disable-web-security
  --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配置如下:

# 前端部署
<VirtualHost *:80>
    ServerName www.xxx.com
    ServerAlias xxx.com
    DocumentRoot /src/angular-js

    # angular-js static files
    <Directory /src/angular-js>
        Options -MultiViews +FollowSymLinks
        Require all granted
    </Directory>

    # Reverse Proxy
    # 关闭正向代理,才可以使用ProxyPass
    ProxyRequests Off
    # 代理api地址
    ProxyPass /api/ http://api.xxx.com/
    # 不跳转url(不重定向)
    ProxyPassReverse /api/ http://api.xxx.com/
    # 把www的cookies改成api的
    ProxyPassReverseCookieDomain api.xxx.com www.xxx.com
    ProxyPassReverseCookiePath / /api/
</VirtualHost>

# 后端部署(用Passenger部署django,可借鉴)
<VirtualHost *:80>
    ServerName api.xxx.com

    # Tell Apache and Passenger where your app's code directory is
    DocumentRoot /src/myProject
    PassengerAppRoot /src/myProject

    # Tell Passenger that your app is a Python app 
    PassengerAppType wsgi
    PassengerStartupFile wsgi.py
    PassengerPython /usr/bin/python3

    # Relax Apache security settings
    <Directory /src/myProject>
      Allow from all
      Options -MultiViews +FollowSymLinks
      Require all granted
    </Directory>
</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,指向如下命令:

sudo a2enmod proxy


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

LoadModule proxy_module modules/mod_proxy.so
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方法

评论列表

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

新的评论

清空