关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
最近用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反向代理有很多配置。具体可以查看官方文档。