Vue实现简单前后端分离(虚拟主机也可用)

流氓凡 技术分享 2020-09-19 7.76 K 0

我们提到前后端分离,第一想到的应该是跨域问题!之前的项目跨域问题我都是在vue端解决,部署上线后通过nginx进行反向代理。

这种方法有个小坑,大家可以尝试下使用Apache搭建后端api,然后使用Nginx进行反向代理转发,在Windows和安卓上没有问题,但是在苹果全家桶(无论是ios、macOS)都无法请求到数据回来。

解决办法当然就是前后端都用Nginx服务器啦。

开始

今天我们利用后端来解决跨域问题的,前端:Vue-cli 3.x 后端:ThinkPHP 5.0 进行简单地配置。期间可能会有一些二次封装方法,大家在使用过程中可以参考下。

准备工作 

两个域名 ,一个做前端一个做 后端api(前后端分离必须的嘛)

服务器或虚拟主机,准备用来搭建前端

一个搭建好ThinkPHP框架的主机

温馨提示:不要用虚拟主机的二级目录搭建Vue了,网上看到很多搜索这方面教程的同学,好不夸张的说那您不如使用Smarty模板引擎。好不容易前端迎来了操作方式大爆发,您一下打回原形了。

前端定义API

我们需要在window全局挂载一个api,不然每次请求都带上那么长一大串域名是不是很恶心?

需要注意的是,这时候在vue.config.js定义的像下面这样的就没有了,可以删除了

devServer: {
    // 本地调试防跨域处理
    port: 8000,
    // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
    proxy: {
        '/api': {
            target: 'https://xxxx.xxx.com/web/index.php?s=/api/',  // target host
            ws: true,  // proxy websockets
            changeOrigin: true,  // needed for virtual hosted sites
            pathRewrite: {
                '^/api': ''  // rewrite path
            }
        },
    }
},

我们在index.html入口中定义一个请求配置挂载到window上 ,大概如下:

<script>
    // 挂载到Window下的全局请求配置
    window.HttpAllConfig = {
        "server": "https://xxxxx.xxx.com/web/index.php?s=/api/",
    }
</script>
<div id="app"></div>

我们在man.js二次封装axjos请求方法后挂载到Vue原型链上,二次封装其实主要是用来检查登陆状态 ,全局异常抛出

/**
 * get  请求
 * @param url
 * @param data
 * @param success
 * @param fail
 * @private
 */
Vue.prototype._get = function (url = '', data, success, fail) {
    let _this = this;
    url = HttpAllConfig.server + url; // 这里组合真正的请求api
    data.params = {
        client: 'h5',
        ...data,
        token: Vue.ls.get('token') // 全局缓存token用于校验用户身份
    };
    _this.axios.get(url, data).then(res => {
        if (typeof res !== 'object') {
            _this.$toast.loading('网络请求出错', {
                coverColor: "rgba(0,0,0,0.5)",
                duration: 300, // 自定义关闭时长
            });
            return false;
        }
        if (res.code === -1) {
            // 登陆失效,并且需要验证登陆
            _this.doLogin();
            return false;
        } else if (res.code === 0) {
            if (res.msg) {
                _this.$toast.loading(res.msg, {
                    coverColor: "rgba(0,0,0,0.5)",
                    duration: 300, // 自定义关闭时长
                });
                _this.$toast.fail(res.msg, function () {
                    fail && fail(res);
                });
            }
            return false;
        } else {
            success && success(res);
        }
    })
}

ok,然后我们模拟请求api,例如:api地址为:https://baidu.com/web/index.php?s=/api/user/detail

// 因为_get方法挂载到了Vue原型链上,后面我们在Vue中就可以使用 
this._get('user/detail',{},res=>{
    console.log(res);
});
// 没看错,这就完成了一次请求数据是不是很简单?

开始配置服务端跨域

目前我现在做微信开发比较多,因此都是在线上环境开发的,phpstrom保存代码自动上传到服务端还是很方便的。因此配置好服务端后,即使在本地调试Vue也不会出现跨域的问题。

我在api服务上新建了一个Controller,继承 think的Controller,里面定义一些请求和返回方法以及权限验证,在初始化方法中方式允许跨域请求代码如下 :

header('Access-Control-Allow-Origin: *');//允许跨域请求
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie');
header('Access-Control-Allow-Credentials: true');//允许跨域请求

当然,这简单的说您可以直接在框架载入文件的index.php方式上面方法也可以。

<?php
if(version_compare(PHP_VERSION,'7.1.3','<'))  die('require PHP > 7.1.3 !');
// [ 应用入口文件 ]
header("Content-type:text/html;charset=utf-8");
header('X-Powered-By: wslmf.com');
header('Access-Control-Allow-Origin: *');//允许跨域请求
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie');
header('Access-Control-Allow-Credentials: true');//允许跨域请求
// 定义运行目录
define('WEB_PATH', __DIR__ . '/');
// 定义应用目录
define('APP_PATH', WEB_PATH . '../source/application/');

// 加载框架引导文件
require APP_PATH . '../thinkphp/start.php';

结尾

我们对Vue文件进行打包,生成的 dist文件放置在服务器目录下,绑定运行目录为dist即可进行访问了 。

使用此方式对运维同学来说还是有点方便的。

这时候有同学会说,查看index.html就能看到api了?

大哥,先说js有不可逆的加密方法,单单说看到api怎么样?即使不在index.html代码中发现,f12有请求就能看到了好么。


评论