vue单页应用+代理跨域接口+ajax文件上传

Posted 前端小砖头

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue单页应用+代理跨域接口+ajax文件上传相关的知识,希望对你有一定的参考价值。

vue-cli搭建一个代理接口的的项目

vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目;当然如果只是讲如何搭建也没意思,网上教程一大把,肯定得送上点其余的干货,关于webpack-dev-server代理接口,前端解决接口跨域的问题,这是我讲的第二个关于前端接口跨域的解决方案了;


1:安装好了 node,我们可以直接全局安装 vue-cli:

npm install -g vue-cli

最新的 vue 项目模板中,都带有 webpack 插件,所以这里可以不安装 webpack

安装完成后,可以使用 vue -V (注意 V 大写)查看是否安装成功

如果提示“无法识别 'vue' ” ,有可能是 npm 版本过低,可以使用 npm install -g npm 来更新版本


2:初始化一个vue+webpack项目

vue init webpack vue-Project

这个命令大白话就是:初始化一个依赖webpack模板的名叫Vue-Project的项目

然后是一系列询问:

? Project name (vue-Project)

项目名称是不是 Vue-Project 直接按回车

然后又问你:

? Project description (A Vue.js project)

项目名称是不是一个vue.js的项目 直接按回车

? Author (fungleo <web@fengcms.com>)

问你作者名,可填写, 直接回车

? Vue build (Use arrow keys)
❯ Runtime + Compiler: recommended for most users
  Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specific html) are ONLY allowed in .vue files -
render functions are required elsewhere

这里是问你,需要不需要安装编译器,我们选择需要安装,也就是第一个,也就是直接回车就OK了。

? Install vue-router? (Y/n)

是否需要安装vue路由(主要是用于单页应用) 直接回车

? Use ESLint to lint your code? (Y/n)

是否需要使用 ESLint来检查你的代码。需要!所以同上,我们直接回车。

? Pick an ESLint preset (Use arrow keys)
❯ Standard (https://github.com/feross/standard)
  Airbnb (https://github.com/airbnb/javascript)  
none (configure it yourself)

然后问你需要使用哪种风格来检查你的代码。我们选择第一个 standard来检查代码。所以,直接回车。

? Setup unit tests with Karma + Mocha? (Y/n)

是否需要安装测试功能。不要。我们输入 n 然后回车

? Setup e2e tests with Nightwatch? (Y/n)

 n 然后回车

等它读完条................................................


配置完成后,可以看到目录下多出了一个项目文件夹,里面就是 vue-cli 创建的一个基于 webpack 的 vue.js 项目

然后进入项目目录(cd Vue-Project)


3:使用 npm 安装依赖

npm install


4:启动项目

npm run dev


如果运行不起来啥的优先看看是不是端口被占用,在项目补录下有个config的文件夹

默认是8080把这个数值改掉,


5:打包项目

如果你没搞东搞西的这时候只需要

npm run build


就会把你src里面的文件打包到项目根目录新生成的dist文件夹里,

项目上线时,只需要将 dist 文件夹放到服务器就行了。


6:使用接口代理服务

直接上代码吧,copy总会吧

覆盖把config文件夹下的index.js

const path = require('path')


module.exports = {

  dev: {

  //静态资源文件夹,默认“static”,

    assetsSubDirectory: 'static',

    //发布路径,

    assetsPublicPath: '/',

    proxyTable: {

//因为在 ajax 的 url 中加了前缀 '/tags',而原本的接口是没有这个前缀的

   '/tags': {    

       target: 'http://10.1.9.152:8095/yuegeche-rest',  // 你需要请求数据的接口域名

       changeOrigin: true,  //是否跨域

       pathRewrite: {

           '^/tags': ''   //如果接口包含该字段都会被代理到本地(该接口就不会跨域了,可以正常请求),

            }              

        }

    },

    port: 8088, 

    // 下面表示项目启动后是否自动打开开浏览器

    autoOpenBrowser: false,

    //是否查询错误

    errorOverlay: true,

    //是否通知错误

    notifyOnErrors: true,

    //是跟devserver相关的一个配置,webpack为我们提供的devserver是可以监控文件改动的,但在有些情况下却不能工作,我们可以设置一个轮询(poll)来解决

    poll: false,

    //是否使用eslint检测代码

    useEslint: true,

    //是否展示eslint的错误提示

    showEslintErrorsInOverlay: false,

    //webpack提供的用来方便调试的配置,它有四种模式,可以查看webpack文档了解更多

    devtool: 'cheap-module-eval-source-map',

    //一个配合devtool的配置,当给文件名插入新的hash导致清楚缓存时是否生成souce maps,默认在开发环境下为true

    cacheBusting: true,

    //是否开启cssSourceMap

    cssSourceMap: true

  },


  build: {

    // 编译输入的index.html文件。node.js中,在任何模块文件内部,可以使用__filename变量获取当前模块文件的带有完整绝对路径的文件名,

    index: path.resolve(__dirname, '../dist/index.html'),

    // 编译输出的静态资源路径

    assetsRoot: path.resolve(__dirname, '../dist'),

    // 编译输出的二级目录

    assetsSubDirectory: 'static',

    // 编译发布的根目录,可配置为资源服务器或者cdn域名

    assetsPublicPath: '/',

    //是否开启cssSourceMap

    productionSourceMap: true,

    devtool: '#source-map',

    // 是否开启gzip(压缩成zip包)

    productionGzip: false,

    // gzip模式下需要压缩的文件的扩展名,设置后会对相应扩展名的文件进行压缩

    productionGzipExtensions: ['js', 'css'],

    //是否开启打包后的分析报告

    bundleAnalyzerReport: process.env.npm_config_report

  }

}

逐行注解理论上应该会比较便于大家的理解,

多环境配置文件,直接上代码

/**

 * 配置编译环境和线上环境之间的切换

 * 

 * routerMode: 路由模式

 * 

 */

let baseUrl; 

let routerMode;

const imgBaseUrl = 'http://10.1.9.150:4869/';

//生产测试环境

if (process.env.NODE_ENV == 'development') {

baseUrl = 'http://localhost:8088/tags';

routerMode = 'hash'

}else{

        //预生产和正式环境

baseUrl = 'http://www.alibaba.com/tags';

routerMode = 'hash'

}

export {

baseUrl,

routerMode,

imgBaseUrl

}


import {baseUrl} from '../config/env';

export const runAsync = (url,data,errBack,type) =>{

url = baseUrl + url;

    var p = new Promise(function(resolve, reject){

        //做一些异步操作

        ((type||'') == 'file')?requestFile(url,data,function(res){resolve(res);},errBack):request(url,data,function(res){resolve(res);},errBack);

    });

    return p;            

}

const request = (url, data, callBack, erroCallBack) =>{

var xhr = new XMLHttpRequest();

xhr.open('POST', url, 'true');

xhr.setRequestHeader("Content-Type", 'application/x-www-form-urlencoded');

xhr.send(convertData(data));

xhr.onreadystatechange = function() {

if(xhr.readyState == 4) {

if(xhr.status == 200) {

(typeof xhr.response == 'string') ? callBack(JSON.parse(xhr.response)): callBack(xhr.response);

} else {

erroCallBack();

}

}

}

function convertData (data){

if(typeof data === 'object') {

var convertResult = "";

for(var c in data) {

convertResult += c + "=" + data[c] + "&";

}

convertResult = convertResult.substring(0, convertResult.length - 1);

return convertResult;

} else {

return data;

}

}

}

const requestFile = (url, data, callBack, erroCallBack) => {

var xhr = new XMLHttpRequest();

xhr.open('POST', url, 'true');

xhr.send(data);

xhr.onreadystatechange = function() {

if(xhr.readyState == 4) {

if(xhr.status == 200) {

(typeof xhr.response == 'string') ? callBack(JSON.parse(xhr.response)): callBack(xhr.response);

} else {

erroCallBack();

}

}

}

}


原创允许转载,莫要copy为你的"原创"ok?



以上是关于vue单页应用+代理跨域接口+ajax文件上传的主要内容,如果未能解决你的问题,请参考以下文章

vue中的代理跨域

解决ajax跨域的办法,代理,cors,jsonp

Vue中的Ajax

vue-cli 配置服务端口反向代理

vue-cli反向代理跨域请求

为什么我的跨域 AJAX 发了两个请求?