1. 程式人生 > >Vue之axios跨域 爬坑

Vue之axios跨域 爬坑

 

axios中只能使用get和post方法來進行請求資料,沒有提供jsonp等方法進行跨域訪問資料

下面我們來解決axios的跨域問題!

建立好vue-cli專案

依賴axios

npm install axios -D

配置:

為什麼要配置一下呢  因為在vue檔案中不能直接引入 axios來使用

找到src/main.js

引入 axios

import axios from 'axios/dist/axios.js'

 設定 axios 為vue示例的全域性方法 

Vue.prototype.$http = axios
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import router from './router'
import 'jquery/dist/jquery.min.js'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'
import axios from 'axios/dist/axios.js'
Vue.config.productionTip = false Vue.prototype.$http = axios /* eslint-disable no-new */ new Vue({ el: '#app', router // components: {} })

 

就這樣 我們先來試試看看能不能跨域請求

http://api.qingyunke.com/api.php?key=free&appid=0&msg=“你的問題”

<template>
  <div>
    <div>
      <h2>菲菲智慧聊天機器人為您服務!!!</h2>
      <label>請輸入問題:</label>
      <input type="text" v-model="msg"/>
    </div>
    <p v-text="tips"></p>
  </div>
</template>

<script>
export default {

  name: 'Robot',
  data () {
    return {
      msg: '',
      tips: '菲菲智慧聊天機器人等待您的提問!!' } }, watch: { msg: function () { this.tips = '請以 ? 結束提問噢!' this.getRobot() } }, methods: { getRobot: function () { // 判斷最後一個字元是否是? if (this.msg.endsWith('?')) { this.tips = '稍等....' let than = this
      //跨域請求 this.$http.get('http://api.qingyunke.com/api.php?key=free&appid=0&msg="+this.msg+"'
) .then(function (response) { than.tips = response.data.content }) .catch(function (error) { console.log(error) }) } } } } </script> <style scoped> </style>

這個時候,我滿懷期待的等待著返回值,但是,結果卻不如人意

下面我們來解決這個問題

如果要使用axios直接進行跨域訪問是不可以的,這是就需要配置代理了,為什麼要配置代理呢?
原因就是因為客戶端請求服務端的資料是存在跨域問題的,而伺服器和伺服器之間可以相互請求資料,是沒有跨域的概念(如果伺服器沒有設定禁止跨域的許可權問題),也就是說,我們可以配置一個代理的伺服器可以請求另一個伺服器中的資料,然後把請求出來的資料返回到我們的代理伺服器中,代理伺服器再返回資料給我們的客戶端,這樣我們就可以實現跨域訪問資料啦。
如果不理解可以看依據看下圖

第一步:http-proxy-middleware中介軟體作為代理

npm install -S http-proxy-middleware

第二步:配置

找到config/index.js

proxyTable: { // 在這裡配置如下程式碼
      '/api': {
        target:'http://api.qingyunke.com/api.php', // 你請求的第三方介面
        changeOrigin:true, // 在本地會建立一個虛擬服務端,然後傳送請求的資料,並同時接收請求的資料,這樣服務端和服務端進行資料的互動就不會有跨域問題
        pathRewrite:{  // 路徑重寫,
          '^/api': '/api'  // 替換target中的請求地址,也就是說以後你在請求http://api.qingyunke.com/api.php這個地址的時候直接寫成/api即可。
        }
      }
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')

module.exports = {
  dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: { // 在這裡配置如下程式碼
      '/api': {
        target:'http://api.qingyunke.com/api.php', // 你請求的第三方介面
        changeOrigin:true, // 在本地會建立一個虛擬服務端,然後傳送請求的資料,並同時接收請求的資料,這樣服務端和服務端進行資料的互動就不會有跨域問題
        pathRewrite:{  // 路徑重寫,
          '^/api': '/api'  // 替換target中的請求地址,也就是說以後你在請求http://api.qingyunke.com/api.php這個地址的時候直接寫成/api即可。
        }
      }
    },

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-

    // Use Eslint Loader?
    // If true, your code will be linted during bundling and
    // linting errors and warnings will be shown in the console.
    useEslint: true,
    // If true, eslint errors and warnings will also be shown in the error overlay
    // in the browser.
    showEslintErrorsInOverlay: false,

    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    cssSourceMap: true
  },

  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',

    /**
     * Source Maps
     */

    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }
}

配置好後再去試試跨域

<template>
  <div>
    <div>
      <h2>菲菲智慧聊天機器人為您服務!!!</h2>
      <label>請輸入問題:</label>
      <input type="text" v-model="msg"/>
    </div>
    <p v-text="tips"></p>
  </div>
</template>

<script>
export default {

  name: 'Robot',
  data () {
    return {
      msg: '',
      tips: '菲菲智慧聊天機器人等待您的提問!!'
    }
  },
  watch: {
    msg: function () {
      this.tips = '請以 ? 結束提問噢!'
      this.getRobot()
    }
  },
  methods: {
    getRobot: function () {
      // 判斷最後一個字元是否是?
      if (this.msg.endsWith('?')) {
        this.tips = '稍等....'
        let than = this
        let url = '/api?key=free&appid=0&msg=' + this.msg + '' // 這裡就是剛才的config/index.js中的/api
        this.$http.get(url)
          .then(function (response) {
            than.tips = response.data.content
          })
          .catch(function (error) {
            console.log(error)
          })
      }
    }
  }
}
</script>

<style scoped>

</style>

結果:

 

 就這樣 axios就跨域成功了!!!