解决跨域问题

跨域是浏览器受同源策略的限制,同源策略是浏览器为确保资源安全,而遵循的一种策略,该策略对访问资源进行了一些限制(如发送 ajax 请求,操作 dom,读取 cookie)。

最常见的影响就是发送 ajax 请求,本文着重讲这部分。

我们将ajax 请求地址称为目标源,将当前页面地址称为称为所处源源=协议+域名+端口,所处源和目标源的协议、域名、端口都相同才是同源,否则就是非同源,即跨域。

注意:
1.跨域限制仅存在浏览器端,服务端不存在跨域限制。
2.即使跨域了,网络请求也可以正常发出,但响应数据不会交给开发者。
3.link、script、img… 这些标签发出的请求也可能跨域,只不过浏览器对标签跨域不做严格限制,对开发几乎无影响。

解决方式:
1.配置CORS
2.配置代理服务器
3.使用JSONP

一、配置CORS

CORS 全称:Cross-Origin Resource Sharing(跨域资源共享),是用于控制浏览器校验跨域请求的一套规范,服务器依照 CORS 规范,添加特定响应头来控制浏览器校验,大致规则如下:
● 服务器明确表示拒绝跨域请求,或没有表示,则浏览器校验不通过。
● 服务器明确表示允许跨域请求,则浏览器校验通过。
tips:使用 CORS 解决跨域是最正统的方式,且要求服务器是“自己人”。

这里用express 框架写了一个接口,地址为http://localhost:3456

app.get("/api/data", (req, res) => {// 模拟数据const data = {name: "John Doe",age: 30,city: "New York",};res.json(data);
});

我们将静态页面也放在http://localhost:3456

// 路由设置,部署前端静态页面
app.get("/", (req, res) => {res.sendFile(path.join(__dirname, "public", "index.html"));
});

此时打开http://localhost:3456,然后发起请求http://localhost:3456/api/data,可以看到能正常获取数据。
在这里插入图片描述

然后我再使用插件Open with Live Server打开页面,地址为http://localhost:5501。
此时在发起请求http://localhost:3456/api/data,可以看到因为跨域问题获取数据失败,但其实请求是成功发送出去的。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在解决跨域问题之前,我们先来了解一下简单请求和复杂请求。
在这里插入图片描述

1.简单请求解决跨域问题

对于简单请求,我们可以在服务器端设置响应头Access-Control-Allow-Origin,允许跨域请求。
Access-Control-Allow-Origin就像设置白名单一样,只有白名单中的源才能访问资源。可以设置为某个源,也可以使用*设置所有源。

app.get("/api/data", (req, res) => {// 允许所有源发起跨域请求// res.setHeader("Access-Control-Allow-Origin", "*");// 允许指定源发起跨域请求(只能指定一个)res.setHeader('Access-Control-Allow-Origin','http://localhost:5501')// 模拟数据const data = {name: "John Doe",age: 30,city: "New York",};res.json(data);
});

配置了Access-Control-Allow-Origin后,我们就可以正常获取数据了。
在这里插入图片描述

2.复杂请求解决跨域问题

复杂请求会在发送请求之前,先发送一个预检请求(preflight request),预检请求是一个 OPTIONS 请求,用于询问服务器是否允许跨域请求。
因此我们需要配置一个options请求处理预检请求。

// 处理预检请求
app.options("/api/data", (req, res) => {// 设置允许的跨域请求源res.setHeader("Access-Control-Allow-Origin", "*");// 设置允许的请求方法res.setHeader("Access-Control-Allow-Methods", "GET");// 设置允许的请求头res.setHeader("Access-Control-Allow-Headers", "Authorization");// 设置预检请求的缓存时间(可选)res.setHeader("Access-Control-Max-Age", 7200);// 发送响应res.send();
});app.get("/api/data", (req, res) => {// 允许所有源发起跨域请求res.setHeader("Access-Control-Allow-Origin", "*");// 模拟数据const data = {name: "John Doe",age: 30,city: "New York",};res.json(data);
});

二、配置代理服务器

1.自己配置代理服务器

安装库npm i http-proxy-middleware

const { createProxyMiddleware } = require("http-proxy-middleware");// 所有带/api前缀的请求都代理到localhost:3456
app.use("/api",createProxyMiddleware({target: `http://localhost:${PORT}`,changeOrigin: true,pathRewrite: {"^/api": "",},})
);
2.借助脚手架搭建服务器

常见的脚手架工具如vitewebpack等,都提供了代理配置选项,可以方便地配置代理服务器。
但是需要注意的是,这个跨域只针对开发环境有效,一旦打包之后,前端配置的跨域就不起作用了,打包后就必须部署在web服务器上,脱离了 vue的代理配置。
以vite为例,在vite.config.js中配置反向代理如下

export default defineConfig({// 配置服务器的代理设置server: {// 代理配置,用于重定向请求到其他服务器proxy: {// 定义一个代理规则,将/api路径下的请求代理到指定的目标服务器'/api': {// 目标服务器的地址target: 'http://localhost:3456',// 更改请求的origin为代理服务器的origin,以便与目标服务器交互changeOrigin: true,// 重写请求路径,移除/api前缀rewrite: (path) => path.replace(/^\/api/, '')}}}
})
3.使用 Nginx 搭建代理服务器

下载nginx下载地址

  1. 在根目录下的conf目录下找到配置文件nginx.conf并打开
  2. 在root属性修改为我们的静态页面的根路径,
  3. 增加反向代理配置。
  4. 修改端口号(可改可不改),默认是80,我这里修改成6789。
  5. 双击根目录下的nginx.exe启动。
    在这里插入图片描述
    打开http://localhost:6789,发起请求http://localhost:3456/api/data,
    在这里插入图片描述

三、JSONP

JSONP 是一种非官方的跨域解决方案,它利用了 script 标签没有跨域限制的特点,通过 script 标签的 src 属性发送请求,服务器返回一个函数调用,函数的参数就是返回的数据。JSONP 只能发送 GET 请求,且需要服务器配合返回数据。

有空再写

参考资料:https://www.yuque.com/tianyu-coder/openshare/aksmvpbebgw7savk

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

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

相关文章

【微知】如何通过命令行在非串口界面触发sysrq的help信息?(echo h > /proc/sysrq-trigger)

背景 在服务器上,触发sysrq通常需要在串口执行sysrq热键,比如 ~相关的操作 如何通过在ssh界面触发sysrq触发一些操作? 命令 通过sysrq指定的/proc接口文件进行操作 echo h > /proc/sysrq-trigger dmesg #产看输出的帮助信息然后根据打…

Junit + Mockito保姆级集成测试实践

一、做好单测,慢即是快 对于单元测试的看法,业界同仁理解多有不同,尤其是在业务变化快速的互联网行业,通常的问题主要有,必须要做吗?做到多少合适?现在没做不也挺好的吗?甚至一些大…

MYSQL-SQL-01-DDL(Data Definition Language,数据定义语言)

DDL(数据定义语言) DDL(Data Definition Language),数据定义语言,用来定义数据库对象(数据库,表,字段) 。 一、数据库操作 1、 查询mysql数据库管理系统的所有数据库 语法&#…

django(3)jinja2模版的使用

启动模版 安装jinja2 pip install jinja2 配置setting TEMPLATES中添加配置 {BACKEND: django.template.backends.jinja2.Jinja2,DIRS: [os.path.join(BASE_DIR,jinja2)], #模版在项目中的所在位置} template中各项的含义 这个配置项中模版自上而下加载,重名…

Spring Boot框架的电影评论系统设计与实现

3系统分析 3.1可行性分析 通过对本电影评论网站实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本电影评论网站采用SSM框架,JAVA作为开发语言&#…

基于单片机的智能小区门禁系统设计(论文+源码)

1总体架构 智能小区门禁系统以STM32单片机和WiFi技术为核心,STM32单片机作为主控单元,通过WiFi模块实现与手机APP的连接,构建整个门禁系统。系统硬件包括RFID模块、指纹识别模块、显示屏、按键以及继电器。通过RFID绑定IC卡、APP面部识别、指…

Linux中Kconfig结构分析

目录结构中,某一层的内容无非就是,要么全是目录,要么全是文件,要么既有目录又有文件,我们的Kconfig文件通常是分布在各级目录中。那么,这些Kconfig如何一层一层地去组织起来呢? 首先明确下&…

VTK的学习方法-第二类型应用

VTK的高级使用方法是自己写一个算法(Filter),本文使用的数据类型位polydata,这个数据类型应用比较广泛。 我们的算法一般是继承VTK里面的vtkpolydataalgorithm,然后自己添加一些变量,重写(over…

京东 北京 java 中级: 哪些情况下的对象会被垃圾回收机制处理掉? 哪些对象可以被看做是 GC Roots 呢?对象不可达,一定会被垃圾收集器回收么?

我同学最近在面试java的岗位, 这是他遇到的某些关于java的JVM中垃圾回收相关的部分的问题, 他来问我, 我特以此文章来解答. 公司 京东 base 北京 面试时间 2024年10月23日16:00:00 他跟我说, 面试官一上来就问了一个关于JVM的问题, 直接就给他难住了, 问题是 : 哪些情况下…

深入理解Qt中的QTableView、Model与Delegate机制

文章目录 显示效果QTableViewModel(模型)Delegate(委托)ITEM控件主函数调用项目下载在Qt中,视图(View)、模型(Model)和委托(Delegate)机制是一种非常强大的架构,它们实现了MVC(模型-视图-控制器)设计模式。这种架构分离了数据存储(模型)、数据展示(视图)和数据操作(委托),使…

通过Python爬虫获取商品销量数据,轻松掌握市场动态

为什么选择Python爬虫? 简洁易用:Python语言具有简洁的语法和丰富的库,使得编写爬虫变得简单高效。强大的库支持:Python拥有强大的爬虫框架(如Scrapy、BeautifulSoup、Requests等),可以快速实现…

【记录】Django数据库的基础操作

数据库连接 在Django中使用 mysqlclient 这个包用于数据库的连接,切换至 Django环境中直接 pip install mysqlclient 安装此包 1 数据库连接配置 在项目目录下的setting.py中配置 DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: mini,#数据库名US…

uniapp修改input中placeholder样式

Uniapp官方提供了两种修改的属性方法&#xff0c;但经过测试&#xff0c;只有 placeholder-class 属性能够生效 <input placeholder"请输入手机验证码" placeholder-class"input-placeholder"/><!-- css --> <style lang"scss" s…

Python的买家秀大揭秘:用代码点亮API数据

在一个充满无限可能的数字世界里&#xff0c;Python侦探正准备开始他的新任务&#xff1a;揭开买家秀API数据的神秘面纱。这不仅是一次技术的挑战&#xff0c;更是一次与时间赛跑的较量。Python侦探&#xff0c;这位编程界的福尔摩斯&#xff0c;打开了他的笔记本电脑&#xff…

C++大坑之——多继承(菱形继承)

文章目录 前言一、多继承是什么&#xff1f;1. 多继承概念2. 多继承语法 二、菱形继承1. 为什么会有菱形继承问题&#xff1f;2. 代码感受菱形继承3. 虚拟继承1&#xff09;虚拟继承概念及语法2&#xff09;虚拟继承的原理 4. 为什么要有虚基表&#xff1f;5. 为什么要有偏移量…

bootloader跳转app卡死(IAP卡死)

1、 关闭所有中断再跳转APP 一般bootloader跳转到APP时要关闭app中用到的中断(防止中断打断程序的运行&#xff0c;导致程序跑飞&#xff09;&#xff0c;那么查看系统中用到的中断&#xff1a;串口中断、滴答定时器中断&#xff0c;所以&#xff0c;跳转之前要关闭这两个中断&…

Vlan和Trunk

VLAN的定义 虚拟局域网&#xff0c;用来在二层网络中隔离广播域不同VLAN的设备在二层网络中无法互相通讯&#xff08;二层隔离技术&#xff09; VLAN的转发过程举例 源MAC字段后加上VLAN TAG字段&#xff0c;其中VLAN ID用来标识VLAN。 PC发送数据帧进入交换机&#xff0c;会…

使用SearXNG-搭建个人搜索引擎(附国内可用Docker镜像源)

介绍 SearXNG是聚合了七十多种搜索服务的开源搜索工具。我们可以匿名浏览页面&#xff0c;不会被记录和追踪。作为开发者&#xff0c;SearXNG也提供了清晰的API接口以及完整的开发文档。 部署 我们可以很方便地使用Docker和Docker compose部署SearXNG。下面给出Docker部署Se…

vscode插件live server无法在手机预览调试H5网页

环境 Window10、vscode&#xff1a;1.94.2、Live Server&#xff1a;v5.7.9、Live Server (Five Server)&#xff1a;v0.3.1 问题 PC端预览没有问题&#xff0c;但是在手机点击链接显示访问失败 排查 1. 是否同一局域网 意思就是电脑、手机是不是访问同一个网络。电脑插得…

微信互助学习平台(lw+演示+源码+运行)

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了微信互助学习平台的开发全过程。通过分析微信互助学习平台管理的不足&#xff0c;创建了一个计算机管理微信互助学习平台的方案。文章介绍了微信互助学习平台的…