跨域
前后端分离开发免不了涉及跨域问题,今天就来说一说它。
当然,这只是我个人的理解,如有错误,欢迎指正
开发环境下的跨域
在Vue中解决跨域:
在前端项目根目录新建 vue.config.js
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
devServer: {
proxy: {
'/api': {
target: 'http://api.server.com',
changeOrigin: true,
ws: true,
pathRewrite: {
'^/api': ''
}
}
}
}
};
什么意思呢,简单来说就是当请求路径中包含 /api
的时候,就把该请求代理到 http://api.server.com
。
不明白?举个例子:
假如我要访问 http://api.server.com
去获取某话题,
axios.get("http://api.server.com/topic/233")
假设你的域名是 server.com
,别看只少了 api
,浏览器就是不让你过,是不是很气?
这就是浏览器的同源策略导致的,也就是跨域问题的根源。
但是!nodejs是没有跨域问题的,于是利用这一点,让nodejs去获取数据不就可以了吗?
希望你不要问nodejs是啥,这个我真的解释不了……
话题转回来,上面的 proxy
配置就是告诉node,当访问路径中有 /api
这个字符串时你就把它接管下来,然后去访问 http://api.server.com
获取数据,然后再把数据给浏览器,Ok,跨域问题解决了!鼓掌~
总的来说就是,浏览器访问
axios.get("http://server.com/api/topic/233")
node发现有 api
便接管请求,转而去访问 http://api.server.com/topic/233
,获得数据后返回给浏览器。
聪明的你或许会问了,路径中的 api
去哪了?
是的,它被吃了,具体来说是被 pathRewrite
给吃了……
说点题外话,我们在开发的时候,访问路径一般是http://localhost:8080/api/topic/233
,问题是打包的时候我们需要把路径换成http://server.com/api/topic/233
,毕竟你的域名不可能是localhost, 手动去换不太现实,我们要配置webpack
让它开发时用localhost
,发布时用server.com
在前端项目根目录建立 .env.development
(开发环境)
// 开发环境下配置
module.exports = {
NODE_ENV = 'development'
VUE_APP_BASE_API = 'http://localhost:8080'
VUE_APP_VERSION = '0.0.2'
}
.env.production
(生产环境)
// 生产环境下配置
module.exports = {
NODE_ENV = 'production'
VUE_APP_BASE_API = 'http://server.com'
VUE_APP_VERSION = '0.0.1'
}
简单说一下使用方法(有机会的话细说):
建立 utils/http.js
文件
import axios from 'axios';
// 创建axios实例
var instance = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 1000 * 12
});
export default instance;
import axios from '@/utils/http';
axios.get("/api/topic/233")
这样,webpack就会自动判断该使用哪个域名了。
线上问题
当你开发好项目,发布到线上后,你会发现之前用的接口全都报错了,why?
我们来捋一下……
由于生产环境没有nodejs为我们代理访问,那么浏览器就会直接去访问接口
http://xxx.com/api/topic/233
我们的前端页面自然是没有这个地址的,因为实际的地址是
http://api.xxx.com/topic/233
那么怎么办呢?
这里就轮到了Nginx的登场了。
目前我们的服务器配置了两个服务,一个是前端页面,一个是api服务,我们需要修改一下前端页面的nginx配置,让它能够代理转发我们的路径。
先上配置:
server {
listen 80;
server_name xxx.com;
root /usr/share/nginx/www/html;
index index.php index.html index.htm;
location /api/ {
proxy_pass http://api.xxx.com/;
}
}
注意到 proxy_pass http://api.xxx.com/;
这一行没有?
这样就能把 http://xxx.com/api/topic/233 代理到 http://api.xxx.com/topic/233 。
注:
server.com 是开发时使用的域名,xxx.com 是购买的域名
域名的最后一定要有 / ,具体的区别见 nginx的proxy_pass路径转发规则浅析
目录:
从零开始搭建网站环境(php-yaf nginx mariadb)第一章
从零开始搭建网站环境(php-yaf nginx mariadb)第二章
从零开始搭建网站环境(php-yaf nginx mariadb)第三章
从零开始搭建网站环境(php-yaf nginx mariadb)番外篇——跨域
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。