Vue实战——使用代理服务器解决跨域问题——No‘Access-Control-Allow-Origin‘ header is present on the requested resource

news2025/2/26 9:28:15

概论:

目录

一、跨域问题是怎么产生的

1.1 跨域问题:

1.2 解决办法

三、开启代理服务器

第一种方式:(存在弊端)

细节问题:(解释两个弊端)

第二种方式:(重要)

配置多个代理


一、跨域问题是怎么产生的

违背同源策略。协议,域名(主机名),端口有一个不同就是跨域。

比如在我的电脑上,我使用localhost:8080端口请求localhost:5000端口获取数据,这样的话就会出现跨域问题,如下图所示:这种情况是端口号不同

      getStudents(){
        axios.get('http://localhost:5000/students')
           .then(
                response=>{
                  // response是响应对象 response.data才是服务器给我们的东西 !!! 很重要
                  console.log('请求成功了',response.data)
                },
                error =>{
                  // 这个地方输出error也可以   error.message是具体的原因
                  console.log('请求失败了了',error.message)
                }
            )
      },

1.1 跨域问题:

把下面的8080端口想象成我们的前端工作人员

如上图所示 在8080端口向5000端口(服务器)发送请求且已经送到了5000端口(服务器),5000端口(服务器)收到请求后也把8080端口想要的数据交给他,但是浏览器并没有进一步的展示出来,因为浏览器发现跨域了,数据就被浏览器拿在手里不进行展示了。

 请求是可以发过去的!!!!!一定要注意!服务器也受到请求并且返回数据了!!!!只是浏览器发现是跨域,将请求来的时候握在手里不展示!!

那怎么证明服务器收到请求并且响应了?

如下图所示,当我们请求5000端口的时候,服务器是有响应的

 

1.2 解决办法

解决跨域:

        1.代理服务器  (用的比较多)

         2.JSONP     

           借助Script标签的src属性,在引入外部资源的时候不受同源策略限制做到的,真正开发用的很少,因为这个地方得前后端人员一起使用,只能解决get请求的跨域问题,很鸡肋但是很巧妙

        3.让后端改cors,携带特殊响应头(真正意义解决跨域)

           但是真实的开发中,响应头不是随便配置的,配置了的结果就是任何人都能找你要数据

下面我们就来介绍一下第一种方法:使用代理服务器解决跨域问题

那我们怎么理解代理服务器(粉色)呢?

      房主中介的作用,左手顾客,右手房东

       类似中间人,本身也是服务器。8080是我们目前所处在的位置(红色),代理服务器和我们处在的位置一个样,也是8080,始终保持一致

当我们在8080(红色)端口向5000端口索要数据的时候,并不会直接发送给5000端口(服务器),而是先发送给代理服务器(粉色8080),然后粉色的代理服务器反手把这次请求发送给了5000;之后5000端口收到代理服务器的请求之后把数据响应给了粉色代理服务器,然后粉色代理服务器又给了红色8080端口,最后红色的8080端口(服务器)接收到响应回来的数据。

 但是有同学会想:那粉色代理服务器8080向5000端口(服务器)发送请求,那不是也跨域么?

       粉色的是代理服务器,蓝色的5000也是服务器,服务器和服务器之前不用ajax打交道用的是http,所以同源策略根本管不到代理服务器与5000之前的请求与响应

 

借助vue-cli开启代理服务器

我们也可以使用Nginx开启代理服务器,但是是在后端也比较麻烦,在这里我们就是用Vue脚手架开启代理服务器即可,比较方便好用,也特别简单

一定要记得代理服务器的端口号要和我们保持一致!!!比如说,我们如果向localhost:5000要数据,那我们就不要写5000了,而是要写localhost:8080,因为我们开启了代理服务器,要和我们保持一致

三、开启代理服务器

我们在哪个地方开启代理服务器呢?

    vue.config.js文件

第一种方式:(存在弊端)

    注意!在proxy中不要写具体的路径,写到端口号即可,不用写后面的/students!!!!

   这样写之后一个粉色的代理服务器就开启了,但是我们在使用之前,记得把脚手架给重启,因为我们修改了配置

  // 开启代理服务器
  devServer:{
    proxy:'http://localhost:5000'
  }

下面的端口号也要改,我们最开始的时候是向5000索要数据,存在跨域问题,现在我们开启了一个粉色的代理服务器,而且代理服务器的端口和我们一致,所以我们写8080就好了

      getStudents(){
        axios.get('http://localhost:8080/students')
           .then(
                response=>{
                  // response是响应对象 response.data才是服务器给我们的东西 !!! 很重要
                  console.log('请求成功了',response.data)
                },
                error =>{
                  // 这个地方输出error也可以   error.message是具体的原因
                  console.log('请求失败了了',error.message)
                }
            )
      },

细节问题:(解释两个弊端)

    1.不能灵活的控制能不能走代理

代理服务器8080并不是把所有的请求都转发给5000,当请求的资源8080就有,这个时候就不会把请求转发给5000(人之常情,很好理解)

     这个public文件夹就相当于我们服务器的根路径,public中有的就相当于我们现在8080有的

比如说我们在这个文件夹下新建一个text.txt文件

 然后我们就在浏览器中进行访问,很顺利的拿到了数据

接下来我们在public中创建一个同名文件

然后再发起请求,我们发现我们所要的请求数据变了,不是刚刚的我们从5000中获得的数据,而是实实在在public文件夹下students文件中的数据

2.第二个弊端就是只能配置一个代理

 

第二种方式:(重要)

'/api':在我们第一种方式的时候存在一个弊端,就是我们不能灵活的操控时候走代理,但是在我们第二种方式中就可以,在我们下段代码中我们发现有'/api',他的作用就是灵活的控制是否走代理

当我们的8080端口发送请求的时候,代理服务器就会问:本次请求的前缀是/api么?  如果是的话就转发到5000,不是的话就不走代理(也可以把api改成别的名字,比如可以改成atguigu

target的作用就是写我们真实的请求地址

ws是用于支持websocket,客户端和服务器的一种通信方式

changeOrigin

       true:不会如实回答自己的端口号是8080   假设对面是5000 我们请求之后这个代理服务器告诉他我也是5000 但是其实并不是(骗人)

      false:会如实回答自己的端口号8080,  不会欺骗5000说自己是5000端口(诚实)

      这个地方是true撒谎好,以防5000端口号做限制不让别的端口访问

   devServer:{
    proxy:{
      // '/api'是请求前缀
      '/api':{
        target:'http://localhost:5000',
        ws:true,
        changeOrigin:true
      }
    }
   }

那么我们axios发起请求的路径也应该有所改变 ,一定是在端口号后面添加

   加前缀就走代理,不加前缀就不走代理

       axios.get('http://localhost:8080/atguigu/students')

当我们发起请求后又出现了下面的错误:

 原因:8080向代理服务器索要数据时带着atguigu,进而代理服务器向5000索要数据的时候也带着atguigu,这样就导致了上图中的404(5000中没有atguigu这个路径)

 

怎么解决?

由代理服务器向5000发送请求时不应该再带着atguigu

添加:   pathRewrite:{'^/atguigu':''},  其中pathRewrite中是用键值对的方式存在的,左侧是正则的匹配条件(匹配所有的atguigu),右边是匹配完了之后编程右边的空白字符串就可以了( 将atguigu字符串转化成空白字符串)

   devServer:{
    proxy:{
      // '/api'是请求前缀
      '/atguigu':{
        target:'http://localhost:5000',
        pathRewrite:{'^/atguigu':''},
         ws:true,
         changeOrigin:true
      }
    }
   }

配置多个代理

           
      '/atguigu':{
        target:'http://localhost:5000',
        pathRewrite:{'^/atguigu':''},
         ws:true,
         changeOrigin:true
      },
      '/demo':{
        target:'http://localhost:5001',
        pathRewrite:{'^/demo':''},
        ws:true,
        changeOrigin:true  
      }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/405387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

el-input设置必填提示(单个多个)

有两种:一种是多个el-input通过同一个el-form表单来限制,这种用得最多的地方就是添加和修改功能;另一种是每个el-input通过各自的el-form表单来限制,这种通常是用在动态添加多个输入框等功能上,话不多说,上才艺噻. 第一种(多个el-input同时限…

【JavaScript】JS实用案例分享:DOM节点转JSON数据 | 标签输入框

🖥️ NodeJS专栏:Node.js从入门到精通 🖥️ 博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长的万字自述) 🖥️ TypeScript知识总结&…

微信小程序--》tabBar底部栏

🏍️作者简介:大家好,我是亦世凡华、渴望知识储备自己的一名在校大学生 🛵个人主页:亦世凡华、 🛺系列专栏:微信小程序 🚲座右铭:人生亦可燃烧,亦可腐败&…

搭建博客,基于vue3 的 vitepress 轻松搞定

Ⅰ、什么是vitepress 💎 vitepress 使用场景 简单的说 ,只要 会用 markdown 语法,就能构建自己的 「博客、笔记、使用文档」等系统 ; ✨ vitepress 优势 优势介绍傻瓜式操作只需要配置 菜单 和 对应的 markdown 就能实现博客、笔…

【Vue脚手架安装教程】

文章目录前言一、安装Node.js二、配置淘宝镜像安装cnpm,将npm设置为淘宝镜像:二、安装vue/cli检查是否安装成功: vue -V 或者 vue --version ![在这里插入图片描述](https://img-blog.csdnimg.cn/7f66366eba81456388fcf28871db0650.png)三、 创建一个vue…

Chrome浏览器的跨域设置

做前后端分离的开发的时候,出于一些原因往往需要将浏览器设置成支持跨域的模式,而且chrome浏览器支持可跨域的设置,但是新版本的chrome浏览器提高了跨域设置的门槛,原来的方法不再适用了。其实网上也有很多大神总结的chrome跨域设…

webpack的面试题(吐血整理)

以下为整理的webpack面试题,如有不足之处,还请大家多多指正。 一、webpack的构建流程 二、对webpack的理解 webpack是一个打包模块化js的工具,在webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子&#…

最常见的六种跨域解决方案

目录: 前言:什么是跨域?JSONPCORS搭建Node代理服务器Nginx反向代理postMessageWebsocket总结 前言:什么是跨域? 跨域就是当在页面上发送ajax请求时,由于浏览器同源策略的限制,要求当前页面和…

jQuery模态弹窗插件(jquery-confirm)

前言 今天为大家分享一款开源的非常轻量且精美的jQuery模态弹窗插件:jquery-confirm,它包含Bootstrap,Material等多种主题供选择。 如果你的前端项目中还在使用jQuery,那么jquery-confirm是你模态弹窗的完美选择。 下面我们就来零距离感受…

IDEA如何运行SpringBoot项目(超详细截图)

【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行! 博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、…

vue中组件的props属性(详)

今天这篇文章,让你彻底学会props属性…… props主要用于组件的传值,他的工作就是为了接收外面传过来的数据,与data、el、ref是一个级别的配置项。 问题一:那props具体是怎么使用呢?原理又是什么呢?往下看…

css绘制3D炫动ikun

今天做一个3D版的ikun。 先准备图片一张 代码浅析 页面整体div.contrainer,舞台div.stage,控制盒子div.control,图片盒子div.imgWrap,js载入div.img列表。 <div class"contrainer"><div class"stage"><div class"control">…

vue项目引入svg图标(完整步骤)

1. 安装svg依赖 在vue中首先需要安装可以加载svg的依赖。 npm安装&#xff1a;npm install svg-sprite-loader --save-dev 2. 创建svg文件夹存放svg图标 创建icons文件夹&#xff0c;在icons文件夹下创建svg文件夹存放本地svg图标。 3. vue.config.js 中配置svg图片 vue.c…

vue中使用echarts实现动态数据绑定、获取后端接口数据

之前几篇echarts的文章是实现了静态的柱状图、折线图、饼状图、地图&#xff0c;在项目中我们肯定是需要获取后端接口&#xff0c;将后端返回的数据显示在图表上&#xff0c;所以这次就记录一下如何实现echarts的动态数据绑定。 简单来讲&#xff0c;就是从接口获取到的数据&a…

Vue生命周期总结(四个阶段,八个钩子函数)

生命周期就是组件或者实例&#xff0c;从创建到被销毁&#xff08;初始化化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载&#xff09;的一系列过程&#xff0c;我们称这是Vue的生命周期 文章目录一、Vue的生命周期阶段二、生命周期钩子函数1. beforeCreate2. created3. be…

ES6+--》熟知JS中的async函数

目录 async函数 await 表达式 async使用形式 async读取文件 async发送AJAX请求 与生成器(Generator)相比 async函数 async函数的返回值为 promise 对象&#xff0c;promise对象的结果由async函数执行的返回值决定。async函数能使得异步操作变得更加方便&#xff0c;简而…

前端开发常用哪些工具软件?

前端开发必备工具&#xff0c;一篇文章一网打尽 文章目录 一、前端提高“生产力”工具 1.WebStorm 2. 远程开发 - VSCode 3. 接口测试 - Postman 4.API在线文档生成和测试 - SwaggerUI 5.抓包工具 - Wireshark 6.通用数据库管理 - DBeaver 7.MD编辑器 - Typora 8.虚拟…

【数字孪生】UE4虚幻引擎与前端Web页面的结合

目录介绍基础准备鼠标穿透设置备注介绍 UE初学者&#xff0c;非专业UE工程师&#xff0c;在项目中需要使用UE4结合前端页面完成三维场景与前端图表的联动效果&#xff0c;自学总结方法&#xff0c;使用的版本为UE4.26。 基础准备 1. 使用Vue、Echarts创建前端页面&#xff0…

异常:TypeError: ‘caller‘, ‘callee‘, and ‘arguments‘ properties may not be accessed on strict mode func

异常&#xff1a;TypeError: ‘caller‘, ‘callee‘, and ‘arguments‘ properties may not be accessed on strict mode func 问题解决 今天我在给博客添加樱花飘落的特效的时候 下载并引入了一个JS 之后打包执行的时候 发现樱花不会动了 检查报错发现是文章标题的报错…

事件监听 页面滚动(页面滚动到某一位置时显示/隐藏某元素,Vue环境)

目录 一、效果展示 二、实现步骤 三、涉及要点 1. Vue 语法 v-show 2. 获取窗口到元素顶端的距离 3. 监听事件 一、效果展示 最近在做项目时有一个网页渲染是这样的&#xff0c;某一个元素在开始不显示&#xff0c;只有当页面滑动到指定的位置时才显示该元素。效果如下&a…