首页 > 其他分享 >关于 AJAX 请求跨域问题在 Vue 项目中的解决方式

关于 AJAX 请求跨域问题在 Vue 项目中的解决方式

时间:2024-02-04 10:46:01浏览次数:32  
标签:Vue 浏览器 跨域 AJAX api proxy 服务器 请求

0. 前言

  1. 关于域,sry刚刚新建文件夹,写好了就换过来

  2. 此文为88岁高龄、入门级前端初心者专用笔记;

  3. 暂时只关心 AJAX 请求受同源策略的影响及在 Vue 项目中的 解决方式 捏;

1. 必要性

1.0 你需要知道

(1)协议、域名、端口都相同,才为同源;

(2)浏览器报跨域错误,并不是服务器没有返回,而是服务器返回了,但是被浏览器拦截了。

(3)所谓的端口,其实可以简单地视作为进程 ID;端口的存在的就是因为服务器响应请求时需要找到具体的进程来响应,但是依靠进程 ID 又太过于依赖操作系统,每次都会发生变化而且无法通知想联系它的客户端,所以干脆统一安排一个窗口,让大家忽略细节,需要某类服务时就找那个窗口就行。

1.1 目的

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么?

很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。

由此可见,"同源政策"是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。

1.2 限制范围

目前,如果非同源,共有三种行为受到同源策略限制:

(1) Cookie、LocalStorage 和 IndexDB 无法读取。

(2) DOM 无法获得。

(3) AJAX 请求不能正常发送。

不受限制同源限制的:

(1) Form表单提交不受同源策略限制。

(2) 默认情况下的静态资源的获取。

静态资源是指在服务器端存储的不会变化的文件,如HTML、CSS、JavaScript、图片、音频、视频等文件。这些文件一般不包含动态内容,每次请求时返回的内容都是固定的。

在后端服务器中,可以设置特定的路由来处理静态资源的访问请求。例如,使用 Node.js 的 Express 框架可以使用 express.static 中间件来处理静态资源的请求。

将静态资源直接编辑放到服务器的指定目录下。当用户访问该服务器时,可以通过URL直接访问到这些静态资源。这种方法适用于小型项目或者对访问速度要求不高的场景。

前端本地图片 HTML <img /> 就是获取静态资源的加载,默认情况下,请求不同源的静态资源不会有跨域问题,且浏览器是用 GET 请求获取的。

但 GET 请求是没有跨域这一说法的是错误的,只是上述情况不会有跨域问题,但在以下两种情况会有:

等获取静态资源标签的 crossOrigin 的属性不为 'use-credentials';

AJAX 发起的 GET 请求;

2. 解决方式

2.1 本地

2.1.1 代理服务器

开发时,npm run dev 等命令会在本地启动一个开发服务器;可以使用 vue.config.js 里的 devServer 配置开发服务器。

devServer: {
// host:'0.0.0.0', // 设置为您的 IP 地址,设置项目可用局域网 IP 地址访问
port: port, 
proxy: {
	"/api": {
		target: process.env.VUE_APP_BASE_API,
		changeOrigin: true,
		pathRewrite: {
		  "^/api": "api"
	}
}
// ...

1./api的作用
用代理首先你得有一个标识,表明请求路径中有这个标识的 ajax 请求要使用当前代理。

2.pathRewrite中 “^/api”:"xxx"的作用
当实际需要请求的路径里面没有“/api”时,就需要 pathRewrite,用"^/api":"",把"/api"去掉,这样既能有正确标识, 又能在请求到正确的路径。

2.1.2 配置后端接口地址

1. 在 .env.production.env.development中配置开发和生成环境的接口地址
VUE_APP_BASE_API  = 'http://localhost:8003'
VUE_APP_BASE_API  = 'http://xxxx:xxxx'
2. 在 request.js 中配置 ajax 请求的 baseURL
// 创建axios实例
const service = axios.create({
  // axios中请求配置有 baseURL 选项,这样所有的请求都会自动加上该基础路径。
  baseURL:  process.env.VUE_APP_BASE_API
})

2.1.3 解决原理

在浏览器地址栏通过 URL 直接访问一个地址时,不存在跨域问题

直接通过地址栏输入发起请求,对于服务器而言,这就是一个正常的浏览器请求,并不涉及到另一个域,也不存在一些脚本攻击,所以浏览器并不会对这种请求加以限制。

代理服务器解决 AJAX 请求时的跨域问题。

跨域,是当前域和目标服务域之间的,即在某个页面向后端发起请求时,才产生了跨域;

不配置代理,请求直接由浏览器发送给后台服务,不同源,产生跨域问题;

配置好 proxy 后,npm run dev ==>  "dev": "vue-cli-service serve",webpack 在本地启动一个代理服务器,我们写的页面作为本地代理服务器上的静态资源,对目标服务器的请求会被代理中间件拦截转发。

// 模拟devServer配置代理后,前端文件及代理服务

const express = require('express');
const proxy = require('http-proxy-middleware');
const app = express();

// 对/api开头的请求进行转发处理
app.use(
  '/api', //表示请求的接口以/api/开头
  proxy({
    target: 'http://localhost:8003', // 目标服务器
    changeOrigin: true,
  })
);

// 将前端项目所在的文件夹设置为静态资源
app.use('/', express.static('./index'));

app.listen(8013);

// proxy的路径匹配
// proxy({...}) - 匹配任意路径,所有的请求都会被代理。
// proxy('/', {...})-匹配任意路径,所有的请求都会被代理。
// proxy('/api', {...})-匹配所有以/api开始的路径。

2.3 远程服务器

浏览器 URL 访问 Web 应用的地址(部署所在服务器外网 IP + 对应协议 port)

Javeweb为什么要前后端分离,可看

前端文件部署在 Nginx 或 Tomcat 服务器上,Web 服务器配置允许跨域即可。

2.3.1 Tomcat

修改 web.xml ,都什么年代了还在前后端不分离部署!嗨呀是我们呀,但不管暂时看不懂捏。

2.3.2 Nginx

nginx.conf

        location / {
            # 目标地址
            proxy_pass http://localhost:8003/;  
            # 设置是否允许 Cookie 传输
            add_header Access-Control-Allow-Credentials true;
            # 允许请求地址跨域 * 做为通配符
            add_header Access-Control-Allow-Origin *; 
            # 允许跨域的请求方法
            add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
            add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

            if ($request_method = 'OPTIONS') {
                return 204;
            }
        }

标签:Vue,浏览器,跨域,AJAX,api,proxy,服务器,请求
From: https://www.cnblogs.com/pupyy/p/18003540

相关文章

  • 零基础入门Vue之皇帝的新衣——样式绑定
    回顾大致掌握了上一节的插值语法我已经可以把想要的数据显示到页面上,并且仅需要修改变量,页面就会跟着实时改变但如果对于已经熟悉前端的人来说,单单有数据还是不太行,还需要css对数据进行样式的修饰,让页面更加好看所本篇将记录记录Class与Style绑定的学习总所周知,想要给D......
  • Vue入门
     CDN引入vuevue常用指令v-for 循环渲染语法:v-for="(item,index)initems"items:遍历的数组item:遍历出来的元素index:索引下标v-bind 动态绑定作用:为空间动态绑定属性值,href,css,etc语法:v-bind:属性名=“属性值”简化::属性名=“属性值” v-if   v-sho......
  • 轻松掌握Vue:一键导出PDF和Word文档的秘诀!
    适用业务需求:将当前页面显示内容导出pdf或者word文件实现思路:先将显示内容转成图片base64地址,再生成相应文件注意:显示内容直接转图片慎用::before、::after这些css,svg图标,不然可能出现生成的图片样式丢失问题,如果确实需要显示svg图标的话目前做法是转成png显示,如有更好方法,欢迎补充......
  • vue2.x的项目运行问题(export,set)
    Windows系统修改package.json文件:"scripts":{"serve":"setNODE_OPTIONS=--openssl-legacy-provider&&vue-cli-serviceserve","build":"setNODE_OPTIONS=--openssl-legacy-provider&&vue-cli-s......
  • vue实现v-html渲染的图片预览
    在v-html属性标签的标签上添加getImg方法<divclass="content"v-html="content"@click="getImg($event)"></div>getImg方法,通过$event可获取用户当前点击的元素相应的内容,这里可以获取所点击图片对应的src。判断拿到src后,添加图片的预览效果就可以了//点击查看图片co......
  • 如何运行vue项目
    如何运行vue项目1、首先,将项目里的“node_modules”文件夹删除,这是vue项目的依赖包。因为“node_modules”文件夹太大,一般不会打包上传到svn、git上的,所以没有这个文件夹就不用删。2、删除package-lock.json。package-lock.json记录了整个node_moudles文件夹的树状结构,还记录......
  • Vue中v-model的原理
    在Vue中,v-model是一个非常强大且常用的指令,它能够让我们轻松地处理表单输入和应用状态之间的双向绑定。它不仅简化了代码编写的过程,还提供了一种高效的方式来管理表单数据。理解v-model的原理对于构建复杂的Vue应用来说是非常重要的。在本文中,我们将深入探讨v-model的实现原理,并通......
  • 在Vue中如何动态绑定class和style属性
    在Vue中,动态绑定class和style属性是我们经常遇到的需求。这个功能允许我们根据不同的条件来动态改变元素的样式,让我们的应用更加灵活和富有交互性。在本篇博客文章中,我将带你深入探索在Vue中如何实现这一功能。首先,让我们了解一下Vue中的class绑定。Vue提供了一种简洁而强大的语法......
  • 尤雨溪说:为什么Vue3 中应该使用 Ref 而不是 Reactive?
    每次有同学学习到 vue3 的时候,总会问:“ref 和 reactive 我们应该用哪个呢?”我告诉他:“我们应该使用 ref,而不是 reactive”。那么此时同学就会有疑惑:“为什么呢?ref 还需要 .value 处理,reactive 看起来会更加简单呢?”嗯....每当这个时候,我都需要进行一次长篇大论来解释......
  • vue学习(二) 路由器
    1.路由rounter的创建步骤1.主页面区分导航区、展示区,导航区不同的链接点击,展示区展示不同的组件内容。2.创建路由器,主要是设置路由模式和路由表(路径和组件对应关系)。3.编写不同组件用于展示区不同的展示内容,vue文件。2.一个简单的demo2.1在App.vue中创建导航区和展示区<......