vue-cli3跨域处理,解决500错误以及Proxy error

目录

1 上代码(使用的是vue-cli3脚手架)

2问题

3 解决办法(度娘????)一个bug找了半天方法?

4 修得正果

5 总结

1 上代码(使用的是vue-cli3脚手架)

1)目录

2) vue.config.js 这里只要看devServer这一项就ok

// vue.config.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
    // 项目部署的基本路径
    // 默认假设你的应用将会部署在域名的根部
    // 比如,https://www.vue-cli.com/
    //如果你的应用是部署在一个子路径下,那么你需要在这里指定子路径,比如,如果你部署在 https://www.my-vue.com/my-app/; 那么将这个值改为 “/my-app/”
    publicPath: "/",

    //将构建好的文件输出到哪里 当运行 vue-cli-service build 时生成的生产环境构建文件的目录。注意目标目录在构建之前会被清除 (构建时传入 --no-clean 可关闭该行为)。
    outputDir: "dist",

    //放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
    assetsDir: "",

    // 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码。这个值会在 @vue/cli-plugin-eslint 被安装之后生效。
    // 设置为 true 时,eslint-loader 会将 lint 错误输出为编译警告。默认情况下,警告仅仅会被输出到命令行,且不会使得编译失败。
    // 如果你希望让 lint 错误在开发时直接显示在浏览器中,你可以使用 lintOnSave: 'error'。这会强制 eslint-loader 将 lint 错误输出为编译错误,同时也意味着 lint 错误将会导致编译失败。
    lintOnSave: true,

    //是否使用包含运行时编译器的 Vue 构建版本。设置为 true 后你就可以在 Vue 组件中使用 template 选项了,但是这会让你的应用额外增加 10kb 左右。
    runtimeCompiler: false,

    // 默认情况下 babel-loader 会忽略所有 node_modules 中的文件。如果你想要通过 Babel 显式转译一个依赖,可以在这个选项中列出来。
    transpileDependencies: [],

    //如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
    productionSourceMap: true,

    //是一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改。
    chainWebpack: () => {},

    //是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
    parallel: require("os").cpus().length > 1,

    // 向 PWA 插件传递选项。
    // https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
    pwa: {},

    // 所有 webpack-dev-server 的选项都支持。注意:有些值像 host、port 和 https 可能会被命令行参数覆写。
    //有些值像 publicPath 和 historyApiFallback 不应该被修改,因为它们需要和开发服务器的 publicPath 同步以保障正常的工作。
    // 代理配
    devServer: {
        host: "0.0.0.0",
        port: 8082, // 端口号
        https: false, // https:{type:Boolean}
        open: true, //配置自动启动浏览器  open: 'Google Chrome'-默认启动谷歌
        // proxy: 'http://localhost:9000' // 配置跨域处理,只有一个代理
        // 配置多个代理
        proxy: {
            "/api": {//配置代理以“/api”
                target: "http://localhost:4000", //目标主机
                ws: true, //代理的WebSockets
                changeOrigin: true, //需要虚拟主机站点
                pathRewrite: {
                    "^/api": ""
                }
            }
        }
    },

    // 第三方插件选项
    // 这是一个不进行任何 schema 验证的对象,因此它可以用来传递任何第三方插件选项。
    pluginOptions: {}
};

3)api/ajax.js代码

import axios from 'axios'
export default function ajax (url, data={}, type='GET') {
    return new Promise(function (resolve, reject) {
        // 执行异步ajax请求
        let promise;
        if (type === 'GET') {
            // 准备url query参数数据
            let dataStr = ''; //数据拼接字符串
            Object.keys(data).forEach(key => {
                dataStr += key + '=' + data[key] + '&'
            });
            if (dataStr !== '') {
                dataStr = dataStr.substring(0, dataStr.lastIndexOf('&'));
                url = url + '?' + dataStr;
            }
            // 发送get请求
            promise = axios.get(url)
        } else {
            // 发送post请求
            promise = axios.post(url, data)
        }
        promise.then(function (response) {
            // 成功了调用resolve()
            resolve(response.data)
        }).catch(function (error) {
            //失败了调用reject()
            reject(error)
        })
    })
}



4)api/index.js代码

import ajax from './ajax'
//const BASE_URL = 'http://localhost:4000'
let BASE_URL = "/api";



export const reqShops = (longitude, latitude) => ajax(BASE_URL+'/shops', {longitude, latitude})

5)App.vue


<template>
    <div id = "app">
        <router-view></router-view>
        <FooterGuide v-show = this.$route.meta.showFooterGuide></FooterGuide>
    </div>
</template>
<script>
    import FooterGuide from "./components/FooterGuide/FooterGuide"
    import {reqShops} from "./api"
    export default {
        components: {
            FooterGuide
        },

        mounted() {
            const result = reqShops(40.10038,116.36867)
            console.log(result);
        }

    }
</script>
<style>
    #app {
        width: 100%;
        height: 100%;
        background: #f5f5f5;
    }
</style>

6)main.js代码

import Vue from "vue";
import App from "./App.vue"
import router from "./router"
import Router from 'vue-router'

const originalPush = Router.prototype.push;
Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
};

new Vue({
  el: "#app",//需要定义一个html文档,然后文档里面仅有一个div,id为app
  render: h => h(App),
  router
});

7)index.html代码中有一个div的id为“#app”

2问题

后端使用npm run start启动,前端使用npm run serve启动,使用postman能请求数据。但是谷歌浏览器控制台出现“500”错误network出现错误:

Proxy error: Could not proxy request /shops?longitude=40.10038&latitude=116.36867 from localhost:8082 to http://localhost:4000/ (HPE_INVALID_VERSION

 

 

 

 

3 解决办法(度娘????)一个bug找了半天方法?

1)看这篇博客以及其他类似博客有感

https://blog.csdn.net/janyxh/article/details/97014527

有说“服务器使用了端口4000”,客户端使用端口“8082”,这两者属于跨域,需要在配置文件vue.config.js实现跨域,使用proxy技术

仔细看了很久,逐个字母字符看,一遍又一遍,我好像没有打错字呀。“target”属性使用了“http:”开头了。到底什么问题?????应该不是跨域

2)看到有些评论说使用Nginx反向代理。脑壳疼啦,我不会用,继续度娘,今天找不到,我就放弃啦!!!!

于是找啊找,找到这个老哥的https://ask.csdn.net/questions/1054158博客

说“开机正常,退出重新登录,就出现500错误proxy error”,这时候还不懂怎么看端口是否被占用,想着按着老哥的重启电脑,端口就不会被占用啦,于是重启电脑,重启项目,postman能调试出来,vue项目不行,大写的难受

3)受2)还有篇文章影响,

https://blog.csdn.net/weixin_37778679/article/details/86523029?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-8&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-8

于是我开始找传说中的端口占用问题。把自己的前后台都关了,然后使用cmd查看端口是否占用.步骤如下:

执行 netstat -aon|findstr 4000”,找到PID,发现PID为“3332”和“5248”被占用(得了,有戏);

执行tasklist|findstr “PID”   寻找相应的进程;

执行命令taskkill /f /t /im 程序名.exe     结束进程

然后悲催啦,有一个进程是另外一个子进程,结束一个得结束好几个。。。还让不让人活了!!!!

 

4)得了,综合半天找到的方法,然后大概确定可能不是跨域的问题,而是端口占用的问题。

终于终于!!!!!!!!瞎猫碰上死耗子,搞好啦!!!

于是修改了服务器端口,相应修改客户端proxy跨域端口,端口由“4000”改为“5000,然后没报错啦!

修改如下:

vue.config.js

 

服务器端端口修改如下:

 

4 修得正果

根据33)重新启动服务器和客户端,得到如下: 搞完之后感觉vue-cli3脚手架可以自由改配置,但是不懂配置的,是真特喵头凸,一个bug一天,哪有那么多闲情搞!!!但是搞完之后,很有成就!

 

 

5 总结

本章出现的错误,首先考虑一下配置中跨域有没有写错!没有,看端口号是否被占用了,没有,继续度娘吧,继续头凸!!!!

 

百里于2020年5月6日

如果有错,请您指出!如有侵权,请联系我删除!

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
在前后端分离的开发模式下,前端和后端是独立的两个系统,前端向后端发送请求时,常常会遇到跨域问题。为了解决这个问题,我们可以在后端进行跨域配置,也可以在前端进行跨域请求。 1. 后端跨域配置 在后端,可以使用 Spring Boot、Node.js、Django 等框架,在配置文件中增加跨域配置,比如在 Spring Boot 中,可以在 application.properties 或 application.yml 中增加以下配置: ``` # 允许所有域名跨域访问 spring.mvc.crossorigin.allowed-origins=* ``` 2. 前端跨域请求 在前端,可以使用以下几种方式解决跨域问题: 2.1 代理请求 通过在前端配置代理服务器,将前端的请求转发到后端服务器上,从而避免跨域问题。比如在 Vue.js 中,可以使用 vue-cli-service 的 proxyTable 配置实现代理请求: ``` // vue.config.js module.exports = { devServer: { proxy: { // 将请求转发到后端服务器上 '/api': { target: 'http://localhost:8080', changeOrigin: true, pathRewrite: { '^/api': '' } } } } } ``` 2.2 JSONP 请求 JSONP 请求是一种利用 script 标签的跨域技术,通过在前端页面中动态创建 script 标签,然后在后端返回一个 JSONP 回调函数,前端就可以获取到后端数据了。比如在 Vue.js 中,可以使用 axios-jsonp 库实现 JSONP 请求: ``` // 安装 axios-jsonp 库 npm install axios-jsonp --save // 使用 axios-jsonp 库发送 JSONP 请求 import axiosJsonp from 'axios-jsonp'; axios({ url: 'http://example.com', adapter: axiosJsonp }) .then(response => { console.log(response); }) .catch(error => { console.error(error); }); ``` 2.3 CORS 请求 CORS 请求是一种支持跨域的 HTTP 请求,前端可以在请求头中增加 Origin 字段,后端可以在响应头中增加 Access-Control-Allow-Origin 字段,从而允许跨域请求。比如在 Vue.js 中,可以使用 axios 库发送 CORS 请求: ``` // 使用 axios 库发送 CORS 请求 axios({ method: 'get', url: 'http://example.com', headers: { 'Origin': 'http://localhost:8080' } }) .then(response => { console.log(response); }) .catch(error => { console.error(error); }); ``` 以上是解决前后端分离跨域问题的几种方案,具体选择哪种方案需要根据项目实际情况来决定。需要注意的是,在使用代理请求时,应该避免将代理服务器暴露在公网上,以避免安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值