一、问题背景

最近在学习Vue.js,用vue做了一个小项目,项目做完那一刻满心欢喜,打算让小伙伴们用手机浏览器打开项目网站开开眼,(注:用公司的华为防火墙做了nat,把办公电脑映射到公网中,即可打卡开发环境的服务器地址),好家伙,还没等我把地址发给小伙伴自己就先发现手机浏览器打开之后和数据渲染有关的页面都有异常。

二、问题描述

服务器电脑(ip:192.168.8.120)浏览器访问服务器地址(http://192.168.8.120:8080),报错cors跨域问题,如下:

access-control-allow-origin header is present on the requested resource

 三、解决过程

step1:vue.config.js的devServer proxy中设置头部Access-Control-Allow-Origin

 proxy代理可以解决跨域的问题,但是没有header有时也会报错,刚好我碰到了。添加header之后,正常访问倒是可以了但是有个警示,具体看step2。

vue.config.js代码片段:(注意:更改设置之后重启下服务,最好是重启下vscode)

const path = require('path')

module.exports = {
  chainWebpack:config => {
    config.resolve.alias
      .set('@', path.join(__dirname, './src'))
  },

  devServer: {
    open:true,
    host:'0.0.0.0',
    port:8080,
    proxy: {
      '/maoyan':{
        target:'https://m.maoyan.com',
        secure:true,
        changeOrigin:true,
        pathRewrite:{
          '^/maoyan':''
        },
        headers:{
          'Access-Control-Allow-Origin':'*'
        }        
      }
    }
  }
}

 step2:新建http.js封装axios并把baseURL设置成location.origin

step1设置成功之后能正常访问了,但是出现了警示:the website requested a subresource from a network that...

大概意思是说项目网站请求了一个子资源(就是跨域请求),因为用户的特殊网络位置(就是指开发服务器电脑,访问本地服务所以特殊)才能请求成功,后面还说了会在新版Google浏览器中阻止这种请求。

丢……好不容易做出来的项目跟我扯个?!不能忍,然后百度了一圈,没有得到有效答案,这也是为什么我这么一个懒得发文章(因为习惯了Word记录学习笔记、问题处理等)的人会来发这个文章,希望能帮到与我一样有强迫症的人。

 事实证明强迫症还是有用的,用其它电脑访问服务器地址直接报错:

error:Network error

 这还了得,这必须解决,不然项目没法上。于是折腾了一番,把movies.vue组件中的代码改写了下:

movies.vue mounted中的代码片段:

async mounted() {
        // url地址是localhost时只能本机浏览器正常访问,其它电脑浏览器访问会出错
        // url地址中的localhost改为本机ip,其它局域网内的电脑即可正常访问
        // let result = await axios.get('http://192.168.8.120:8080/maoyan/ajax/movieOnInfoList', {
          
        //   console.log(location.origin)      
        this.url = location.origin.concat('/maoyan/ajax/movieOnInfoList')

        let result = await axios.get(this.url, {
          let result = await axios.get('http://localhost:8080/maoyan/ajax/movieOnInfoList', {
            params:{
                token:'',
                optimus_uuid:'2844DB1002DA11EC98E177E830E4C7225440926033F64F25B252247750770B25',
                optimus_risk_level:71,
                optimus_code:10
            }
        })
        this.movieList = result.data.movieList       
    },

step3:创建http.js工具封装axios做request请求

上面的写法不够优雅,又是this.url、又是concat的,得封装下,下次用到时也方便。于是新建了http.js对axios封装:

http.js代码片段:

import axios from 'axios'

class Http {
    constructor(){
        this.instance = axios.create({
            baseURL:location.origin,
            timeout:5000
        })
    }

    get({url, params={}}){
        return new Promise((resolve, reject) => {
            this.instance.get(url, {
                params
            })
                .then((result) => {
                    resolve(result)
                })
                .catch((err) => {
                    reject(err)
                })            
        } )
    }
}

export default Http

转载请声明,谢谢!

完!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐