解决跨域的三种方案

article/2025/9/20 6:58:06

解决跨域的三种方案

  1. 到目前为止,我们编写的 GET 和 POST 接口,存在一个很严重的问题:不支持跨域请求

  2. 解决接口跨域问题的方案主要有三种

  • CORS (主流的解决方案,推荐使用)

  • 代理 (推荐使用)

  • JSONP (有缺陷的解决方案:只支持 GET 请求)

3.代码演示

<!DOCTYPE html>
<html lang="en">
​
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="axios"></script>
</head>
​
<body><button class="btn1">get</button><button class="btn2">post</button>
​<script>document.querySelector('.btn1').addEvnetListener('click',function () {axios({method:'get'url: 'http://localhost',params:{name:'tom',age:10}})     })document.querySelector('.btn2').addEvnetListener('click',function () {axios({method:'post'url: 'http://localhost',data:{bookname:'百年孤独',author:'加西亚·马尔克斯'}})     })</script>
</body>
​
</html>

4.报错提示

这个时候我们会发现出现报错,那么原因是什么呢,就是跨域问题,我们编写的 GET 和 POST 接口,不支持跨域请求

一、使用 cors 中间件解决跨域问题(主流的解决方案,推荐使用)

  1. cors 是 Express 的一个第三方中间件。通过安装和配置 cors 中间件,可以很方便地解决跨域问题

  2. 底层原理:设置一个响应头,响应头部中携带一个 Access-Control-Allow-Origin 字段

  3. 使用步骤

    • 安装中间件: npm install cors

    • 导入中间件: const cors = require('cors')

    • 配置中间件: 在路由之前调用app.use(cors())

  4. 代码演示

// 导入 express 模块
const express = require('express')
​
// 创建 express 的服务器实例
const app = express()
​
// 导入中间件
const cors = require('cors')
// 配置中间件
app.use(cors())
​
// 配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }))
​
// 导入路由模块
const router = require('./020-apiRouter')
// 把路由模块,注册到 app 上
app.use('/api', router)
​
// 调用 app.listen 方法,指定端口号并启动 web 服务器
app.listen(3000, () => {console.log('running……')
})

2.2 什么是 CORS 以及注意事项

  1. CORS (跨域资源共享) 由一系列 HTTP响应头组成,这些 HTTP 响应头决定浏览器 是否阻止前端 JS 代码跨域获取资源

  2. 浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如果接口服务器配置了 CORS 相关的 HTTP 响应头,就可以解除浏览器端的跨域访问限制

  1. CORS主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了CORS的接口

  2. CORS 在浏览器中有兼容性。只有支持 XMLHttpRequest Level2 的浏览器,才能正常访问开启了 CORS 的服务端接口(例如:IE10+、Chrome4+、FireFox3.5+)

2.3 了解 Access-Control-Allow-Origin

响应头部中可以携带一个 Access-Control-Allow-Origin 字段

例如,下面的字段值将只允许来自 http://localhost 的请求

如果指定了 Access-Control-Allow-Origin 字段的值为通配符 *,表示允许来自任何域的请求

二、使用代理解决跨域问题(推荐使用)

原理: ajax跨域去第三方接口请求数据是拿不到的,因要遵循同源策略. 但是去自己的服务器要数据是不是就遵循同源策略了.再让自己的服务器去第三方的接口服务器取数据.最后再返回给ajax

跨域-Vue-Cli配置代理

在前端服务和后端接口服务之间 架设一个中间代理服务,它的地址保持和前端服务一致,那么:

1、代理服务和前端服务之间由于协议域名端口三者统一不存在跨域问题,可以直接发送请求

2、代理服务和后端服务之间由于并不经过浏览器没有同源策略的限制,可以直接发送请求

这样,我们就可以通过中间这台服务器做接口转发,在开发环境下解决跨域问题,并且在vue-cli已经为我们内置了该技术,我们只需要按照要求配置一下即可

vue-cli解决跨域配置说明:

分析前准备:

前端网站地址:http://localhost:8080

服务端网址:http://localhost:5000

有两个配置方法

方法一:

在vue.config.js中添加如下配置:

devServer:{proxy:'http://localhost:5000'
}

说明:

1.优点:配置简单,请求资源时直接发给前端(8080)即可。

2.缺点:不能配置多个代理,不能灵活的控制请求是否走代理。

3.工作方式:若按照上述配置代理,当请求了前端步存在的资源时,那么该请求会转发给服务器(优先匹配前端资源)

方法二(实际使用):

编写vue.config.js配置具体代理规则:

module.exports = {devServer:{proxy:{'/api1':{//匹配所有以'/api1'开头的请求路径target:'http://localhost:5000',//代理目标的基础路径changeOrigin:true, //设置changeOrigin的值为true可以代理反向的地址pathRewrite:{'^/api1':''}  //重写路径,将api开头的路径改为''},'/api2':{//匹配所有以'/api2'开头的请求路径target:'http://localhost:5001',//代理目标的基础路径changeOrigin:true,//设置changeOrigin的值为true可以代理反向的地址pathRewrite:{'^/api2':''}  //重写路径,将api开头的路径改为''},}}
}
​

说明:可以配置多个代理,且可以灵活的控制请求是否走代理

注意:请求资源时必须加前缀

强调:

  1. vue-cli集成了跨域代理功能------ 只能用在开发阶段

  2. changeOrigin,pathRewrite是可选的,可写可不写

    changeOrigin默认值为true。

    changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000 changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080

  3. ajax的基地址baseUrl必须是相对地址,而不能是绝对地址

  4. 修改了vue.config.js,必须要重启服务器

三、JSONP (有缺陷的解决方案:只支持 GET 请求)

JSONP的底层原理

总结:

动态的创建script标签,给script添加一个src属性,他会发送一次异步请求,请求发送了,数据回来了,但是我们获取不到这个数据,我们在这个地方有一个技巧,在我们当前的前端页面声明一个函数,从我的服务器发回来的是一个函数调用

完整的实现过程

JSONP 在底层,用到了 <script> 标签的 src 属性

原因:

<script> 标签的 src 属性,不受浏览器同源策略的限制

可以把非同源的 JavaScript 代码请求到本地,并执行

JSONP 的底层实现原理 - P1

把非同源的 JavaScript 代码请求到本地,并执行

结论: script的src属性值可以获取网络上任意的资源

JSONP 的底层实现原理 - P2

如果请求回来的 JavaScript 代码只包含函数的调用,则需要程序员手动定义 show 方法。示例代码如下:

缺点:服务器响应回来的代码中,调用的函数名是写死的

JSONP 的底层实现原理 - P3

在指定 <script> 标签的 src 属性时,可以通过查询参数中的 callback,自定义回调函数的名称:

JSONP 的底层实现原理 - P4

在指定 <script> 标签的 src 属性时,还可以通过查询参数的方式,指定要发送给服务器的数据:

代码演示:

<!-- script: src js文件link: href css文件a: href   链接img: src  图片以上的这些标签都可以去第三方找资源--><!-- <img src="./xxx.png" alt=""><img src="网络地址" alt=""> --><!-- <img src="https://img2.baidu.com/it/u=4052168682,2290396488&fm=253&fmt=auto&app=138&f=JPEG?w=211&h=252" alt=""> --><!-- <script src=""></script> --><!-- 1.script中的src 可以去第三方地址要资源(跨域) --><!-- <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script> --><!-- 2. src可以拿到服务器的数据 --><!-- <script src="http://localhost/get"></script> --><!-- 3. src可以传递参数的.   思考:能不能动态的传参   不能--><!-- <script src="http://localhost/get?num=100"></script> --><!-- <script src="http://localhost/get?num="+1000></script> --><script>// 在当前页面声明一个函数function show(data){console.log(data);}const num = 1000// 重点: 动态的创建标签 发送请求   返回的数据是"异步"的const script = document.createElement('script')script.src = "http://localhost/get?callback=show&num="+numdocument.body.appendChild(script)// 异步的打印不出来// console.log(abc);// 技巧:  从服务器返回的是函数调用// show(1000)</script>


http://chatgpt.dhexx.cn/article/Elf6qJhC.shtml

相关文章

跨域的五种解决方案详解

1.跨域解决方案一:cors技术 CORS :全称cross origin resource share &#xff08;资源共享&#xff09; 工作原理&#xff1a; 服务器 在返回响应报文的时候&#xff0c;在响应头中 设置一个允许的header res.setHeader(‘Access-Control-Allow-Origin’, ‘*’) CORS :全称…

Java中parseInt用法(double类似)

1.将字符直接解析为十进制数进行输出 2.如果方法有两个参数&#xff0c; 使用第二个参数指定的基数&#xff0c;将字符串参数解析为有符号的10进制整数。&#xff08;所谓指定基数&#xff1a;就是将字符串指定为2&#xff0c;8&#xff0c;16等进制数&#xff0c;然后用解析为…

javascript:parseInt用法,特殊用法,进制转换

parseInt( string,radix ) 一、功能&#xff1a; 除了我们众所周知的字符串转换为整数以外&#xff0c;还涉及到进制问题&#xff1a; 将 [ 指定进制的 ] 字符串转换为十进制整数型 用汉语翻一下这个方法&#xff1a; 二、参数&#xff1a; 1、string: 要解析的字符串&a…

前端JS字符串转数值 Number和parseInt用法

Number() 只包含数值的字符串字符串为空则为0 parseInt() 字符串不能为空字符串第一个必须为数值从第一个数值开始取&#xff0c;到最后一个连续数值结束

java中Integer.parseInt用法详细分析(全)

目录 前言函数讲解 前言 将数字字符串转化成原生整型数据 属于java.lang.Integer 是原生类型整型的包裹类 函数讲解 1.parseInt(String s) 将字符串s转换为十进制的数字&#xff0c;默认为十进制 public static void main(String[] args) {int numInteger.parseInt("10…

parseInt用法

MDN: 从给定的字符串中解析出的一个整数。 代码&#xff1a; <script>var aparseInt("100px");console.log("a:"a" type:"typeof(a));</script>效果&#xff1a;

parseInt鲜为人知的用法

用法一&#xff1a;将小数转换成整数 var float_num 3.14;float_num parseInt(float_num);console.log(float_num);输出结果&#xff1a; 用法二&#xff1a;以数字开头的字符变量转换成整数 var str_num 3.14string;str_num parseInt(str_num);console.log(str_num);输出…

javax.servlet.http.HttpServletRequest错误

javax.servlet.http.HttpServletRequest错误 javax这个api出错 问题分析&#xff1a;javax.api找不到。 解决方案&#xff1a; 方案一&#xff1a; 可以再maven的pom.xml文件中导入方案二&#xff1a; idea没有导入tomcat下的lib目录下的api,我们手动导入就可以。 步骤如下&a…

java: 程序包javax.validation不存在

之前&#xff0c;有位同学反馈说&#xff0c;在运行newbee-mall-api项目时遇到了下面这个问题&#xff0c;无法正常编译项目&#xff0c;错误截图如下&#xff1a; 看了一下应该是NotEmpty、Valid这几个验证注解引起的&#xff0c;因为这几个注解都是定义在javax.validation包…

maven install 时提示程序包javax.crypto不存在

maven install 时提示程序包javax.crypto不存在 大家好&#xff0c;我是酷酷的韩~ 一.maven install报错原因 javax.crypto是在jdk的jre\lib目录下的,需要在编译的时候引入jdk的rt.jar包和jce.jar包。 二.解决办法 <build><plugins><plugin><groupId&…

javax.crypto.AEADBadTagException: Tag mismatch 的解决办法

问题概述 关于这个问题&#xff0c;博主是在微信支付开发与配置过程中遇到的&#xff0c;在使用工具 “ CertificateDownloader-1.1.jar ” 生成平台证书时&#xff0c;报&#xff1a;“ javax.crypto.AEADBadTagException: Tag mismatch! ” ,提示标签不匹配&#xff0c; 如下…

java javax.servlet_java.lang.NoClassDefFoundError: javax/servlet/ServletOutputStream 报错解决

报错的方法栈 在ssm中写了一个 utils 类&#xff0c;定义了main方法测试和查看工具实际数据 运行main方法时报错了&#xff0c;之前都没错&#xff0c;莫名其妙报了错 java.lang.NoClassDefFoundError: javax/servlet/ServletOutputStream at java.lang.Class.getDeclaredMetho…

javax 和hibernate 的NotBlank

问题&#xff1a;hibernate版本在5 的时候&#xff0c;如果你用了 import javax.validation.constraints.NotBlank; 在校验的时会报错 HV000030: No validator could be found for constraint javax.validation.constraints.NotBlank validating type java.lang.String. Chec…

java和javax的区别

java与javax的区别分析 Java是一种受C语言影响的编程语言。Java和Javax本质上是与Java编程语言的上下文一起使用的包。实际上Java和Javax没有区别。这只是不同的名字。Java是一种编程语言&#xff0c;受到C语言的影响。它源自C和C的大部分语法&#xff0c;但是它的低级别设施比…

使用 javax.mail 发送邮件

发邮件在 java web 项目中是一个常用功能&#xff0c;之前在项目中刚好用到了邮件发送功能&#xff0c;现在用博客进行记录&#xff0c;方便以后查阅。这篇文章简单介绍使用 javax.mail 发送邮件的步骤&#xff0c;并提供封装好的邮件发送方法&#xff0c;希望对自己和别人有用…

javax.validation校验整理

文章目录 前言一、非空校验二、长度校验三、数值校验四、正则校验五、自定义校验注解六、校验组 前言 javax.validation校验总是混淆&#xff0c;特此整理。如有错误&#xff0c;请不吝指正。 一、非空校验 序号注解解释适用场景1NotNull不能为null&#xff0c;但可以为empt…

Java API学习(二)javax包

在线中文api&#xff1a;http://tool.oschina.net/apidocs/apidoc?apijdk-zh Java版本&#xff1a;1.8 Android版本&#xff1a;23 java的api有java和javax2个包 java和javax都是Java的API包&#xff0c;java是核心包&#xff0c;javax的x是extension的意思&#xff0c;也就…

知识图谱和图神经网络

知识图谱 理论知识知识图谱嵌入模型TransEDistMult 知识图谱的抽取与构建知识图谱工程知识抽取——实体识别与分类知识抽取——实体关系抽取与属性补全 知识图谱的推理常见知识图谱推理方法分类 图表示学习随机游走同构图算法异构图算法 图神经网络系列监督学习或半监督学习模型…

图神经网络和常见的神经网络的区别

GNN-Graph Neural Networks 0 前言1 图神经网络和以往深度学习的区别2 图神经网络的特点 参考知乎&#xff1a;https://zhuanlan.zhihu.com/p/136521625 0 前言 图神经网络有很多比较好的综述&#xff1a; 1、Graph Neural Networks: A Review of Methods and Applications.…

图神经网络(Graph Neural Networks)

图神经网络&#xff08;Graph Neural Network&#xff09;在社交网络、推荐系统、知识图谱上的效果初见端倪&#xff0c;成为近2年大热的一个研究热点。然而&#xff0c;什么是图神经网络&#xff1f;图和神经网络为什么要关联&#xff1f;怎么关联&#xff1f; 本文简单介绍GN…