当前位置: 首页 > news >正文

前端访问后端实现跨域

背景:前端在抖音里做了一个插件然后访问我们的后端。显然在抖音访问其他域名肯定会跨域。

解决办法:

1、使用比较简单的jsonp

JSONP

优点:JSONP 是通过动态创建 <script> 标签的方式加载外部数据,属于跨域数据请求的一种传统解决方案。JSONP 不会受到浏览器的同源策略限制,因此在某些跨域环境(如抖音小程序中)可以正常工作。

缺点:只能进行 GET 请求,无法支持 POST、PUT 等其他 HTTP 方法。

安全性较低,因为 JSONP 将代码直接注入到页面中,存在潜在的安全风险。

测试案例:

后端 springboot

@RestController
@Slf4j
@RequestMapping("/api")
public class CrosController {@GetMapping("/author/info")public String crosTest(@RequestParam("authorName") String authorName,@RequestParam(value = "callback", required = false) String callback){// 参数校验if (authorName == null) {return "Invalid request: authorName is required";}// 模拟返回数据String jsonData = "{\"author_id\": 12345, \"author_name\": \"" + authorName + "\"}";// 判断是否为 JSONP 请求if (callback != null && !callback.isEmpty()) {// JSONP 响应String jsonpResponse = callback + "(" + jsonData + ");";return jsonpResponse;} else {// 普通 JSON 响应return jsonData;}}}

前端html页面

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body></body></html><script>function jsonpRequest(url, params, callbackName) {return new Promise((resolve, reject) => {// 动态创建回调函数名称const uniqueCallback = callbackName || `jsonpCallback_${Date.now()}`;// 将回调函数注册到全局对象中window[uniqueCallback] = function (response) {// 清理全局回调函数和 script 标签delete window[uniqueCallback];document.body.removeChild(script);// 返回响应数据resolve(response);};// 构建完整的 URL(拼接参数)const query = Object.entries(params).map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join("&");const fullUrl = `${url}?${query}&callback=${uniqueCallback}`;// 创建 script 标签const script = document.createElement("script");script.src = fullUrl;// 处理加载失败script.onerror = function () {delete window[uniqueCallback];document.body.removeChild(script);reject(new Error("JSONP request failed"));};// 插入 script 标签到文档中document.body.appendChild(script);});
}// 使用示例
const url = "http://localhost:8080/api/author/info";
const params = { authorName: "烟火中的水滴" };jsonpRequest(url, params).then((data) => {console.log("Author Info:", data);}).catch((error) => {console.error("Error:", error);});</script>

然后打开次页面。
1、打开控制台 2、执行 可以看到结果正常返回了

jsonpRequest(url, params).then((data) => {console.log("Author Info:", data);}).catch((error) => {console.error("Error:", error);});

在这里插入图片描述

2、@CrossOrigin 解决跨域

Spring Boot 的 @CrossOrigin 注解用于配置 CORS(跨域资源共享),它允许你的后端接受来自其他域的请求。

优点:CORS 是更现代、更安全的跨域解决方案,相比 JSONP,支持所有 HTTP 方法(如 GET、POST 等)。安全性高,因为 CORS 会进行严格的域名、方法等验证。
缺点:如果客户端(如抖音小程序)对 CORS 的处理有限,可能无法支持复杂的预检请求(如 OPTIONS 请求)。CORS 依赖浏览器的支持,如果环境对跨域限制较为严格(如一些小程序环境),可能 CORS 不生效。
我们先开启后端运行起来。看一些问题

1、通过控制台源null模拟跨域

后端代码

@RestController
@Slf4j
@RequestMapping("/api")
public class CrosController {@GetMapping("/author/info/cross")public String crossTest(@RequestParam("authorName") String authorName){// 参数校验if (authorName == null) {return "Invalid request: authorName is required";}// 模拟返回数据String jsonData = "{\"author_id\": 12345, \"author_name\": \"" + authorName + "\"}";return jsonData;}}

1、通过curl
请求
curl 'http://localhost:8080/api/author/info/cross?authorName=123'
结果
{"author_id": 12345, "author_name": "123"}
这个属于正常的
2、打开一个index.html 然后控制台通过 前端代码访问这个接口

fetch('http://localhost:8080/api/author/info?authorName=烟火中的水滴').then(response => response.json()).then(data => console.log("JSON Response:", data)).catch(error => console.error("Error:", error));

发现报错
在这里插入图片描述
问题分析
错误提示:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource 表示目标服务器(http://localhost:8080)没有返回允许跨域访问的CORS响应头。
浏览器的安全机制会拦截请求响应。
根本原因:
客户端代码运行的index.html被浏览器认为是从null源加载的(例如直接从文件系统打开),与http://localhost:8080是不同源。
目标服务器未配置CORS。
其实这个就是跨域了因为你从一个控制台打开访问8080端口 但是你不是同源的就会报错。
那么解决办法就是加一个注解

 @CrossOrigin(origins = "*") // 允许指定来源跨域@GetMapping("/author/info/cross")public String crossTest(@RequestParam("authorName") String authorName){// 参数校验if (authorName == null) {return "Invalid request: authorName is required";}// 模拟返回数据String jsonData = "{\"author_id\": 12345, \"author_name\": \"" + authorName + "\"}";return jsonData;}

重新访问
fetch('http://localhost:8080/api/author/info/cross?authorName=烟火中的水滴') .then(response => response.json()) .then(data => console.log("JSON Response:", data)) .catch(error => console.error("Error:", error))
成功了
在这里插入图片描述
我们看下他发起的curl请求参数:

curl 'http://localhost:8080/api/author/info/cross?authorName=%E7%83%9F%E7%81%AB%E4%B8%AD%E7%9A%84%E6%B0%B4%E6%BB%B4' \-H 'Accept: */*' \-H 'Accept-Language: zh-CN,zh;q=0.9' \-H 'Connection: keep-alive' \-H 'Origin: null' \-H 'Sec-Fetch-Dest: empty' \-H 'Sec-Fetch-Mode: cors' \-H 'Sec-Fetch-Site: cross-site' \-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36' \-H 'sec-ch-ua: "Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"' \-H 'sec-ch-ua-mobile: ?0' \-H 'sec-ch-ua-platform: "macOS"'

源是null实际也属于跨域的。
上面是的源是null 我们接下来用python模拟一个源请求
模拟跨域,就得开启一个前端服务器 然后请求后端。

2、模拟前端服务器 端口3000实现跨域

使用 Python(自带)启动 HTTP 服务器: 在终端中进入你的 index.html 所在的目录,并运行以下命令:
python -m http.server 3000
在这里插入图片描述

这会在 localhost:3000 上启动一个 HTTP 服务器。然后在浏览器中访问:
然后打开浏览器 访问 http://localhost:3000/index.html
打开控制台执行
fetch('http://localhost:8080/api/author/info/cross?authorName=烟火中的水滴') .then(response => response.json()) .then(data => console.log("JSON Response:", data)) .catch(error => console.error("Error:", error))
在这里插入图片描述
最后我们打开Network看下他发起的请求是不是真的跨域了。
通过查看curl命令确实跨域了

curl 'http://localhost:8080/api/author/info/cross?authorName=%E7%83%9F%E7%81%AB%E4%B8%AD%E7%9A%84%E6%B0%B4%E6%BB%B4' \-H 'Accept: */*' \-H 'Accept-Language: zh-CN,zh;q=0.9' \-H 'Connection: keep-alive' \-H 'Origin: http://localhost:3000' \-H 'Referer: http://localhost:3000/' \-H 'Sec-Fetch-Dest: empty' \-H 'Sec-Fetch-Mode: cors' \-H 'Sec-Fetch-Site: same-site' \-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36' \-H 'sec-ch-ua: "Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"' \-H 'sec-ch-ua-mobile: ?0' \-H 'sec-ch-ua-platform: "macOS"'

相关文章:

前端访问后端实现跨域

背景&#xff1a;前端在抖音里做了一个插件然后访问我们的后端。显然在抖音访问其他域名肯定会跨域。 解决办法&#xff1a; 1、使用比较简单的jsonp JSONP 优点&#xff1a;JSONP 是通过动态创建 <script> 标签的方式加载外部数据&#xff0c;属于跨域数据请求的一种…...

TCP和UDP通信基础

目录 1. 套接字 (Socket) 2. 基于TCP通信的流程 服务器端 客户端 1. TCP通信API 1.1 创建套接字描述符socket 1.2 绑定IP和端口号bind 1.3 设置监听状态 listen 1.4 接受连接请求 accept 1.5 发送数据 send 1.6 接收数据 recv 2. TCP服务器代码示例 代码解释&…...

微服务中的技术使用与搭配:如何选择合适的工具构建高效的微服务架构

一、微服务架构中的关键技术 微服务架构涉及的技术非常广泛&#xff0c;涵盖了开发、部署、监控、安全等各个方面。以下是微服务架构中常用的一些技术及其作用&#xff1a; 1. 服务注册与发现 微服务架构的一个重要特性是各个服务是独立部署的&#xff0c;因此它们的地址&am…...

找出字符串第一个匹配项的下标

找出字符串第一个匹配项的下标 题目描述&#xff1a; 题解思路&#xff1a; 图上所示&#xff0c;利用字符滑动&#xff0c;如果匹配就字符开始移动&#xff1b;如果不匹配成功&#xff0c;则停止移动&#xff0c;并回到字符串刚开始匹配的字符下标前一个&#xff0c;为下一次…...

面向FWA市场!移远通信高性能5G-A模组RG650V-NA通过北美两大重要运营商认证

近日&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;其旗下符合3GPP R17标准的新一代5G-A模组RG650V-NA成功通过了北美两家重要运营商认证。凭借高速度、大容量、低延迟、高可靠等优势&#xff0c;该模组可满足CPE、家庭/企业网关、移动热点、高清视频…...

Matlab实现北方苍鹰优化算法优化随机森林算法模型 (NGO-RF)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 北方苍鹰优化算法&#xff08;Northern Goshawk Optimization, NGO&#xff09;是一种新颖的群智能优化算法&#xff0c;灵感源自北方苍鹰捕食时的策略。该算法通过模拟苍鹰的搜寻、接近和捕捉猎物的行为模式&am…...

搭建环境 配置编译运行 mpi-test-suite

1&#xff0c;编译安装 ucx 下载源码&#xff1a; $ git clone https://github.com/openucx/ucx.git $ ​git checkout v1.17.0 ​ 运行auto工具&#xff1a; $ ./autogen.sh $ ./autogen.sh 指所以运行两次是因为有时候第一次会失败&#xff0c;原因未查。 配置 ucx $ m…...

夜神模拟器启动报错:虚拟机启动失败 请进行修复 关闭hyper-v

不是关闭hyper-v的问题。 点那个没用。 解决办法&#xff1a; 我电脑win11&#xff08;win10 win11都一样 &#xff09;去安全中心-设备安全性 把内存完整性关了。 这还不够。 在右上角找系统信息 我发现VT显示没开 于是我去BIOS中开启VT 这个VT怎么开很简单。就是你F2 F1…...

投资策略规划最优决策分析

目录 一、投资策略规划问题详细 二、存在最优投资策略&#xff1a;每年都将所有钱投入到单一投资产品中 &#xff08;一&#xff09;状态转移方程 &#xff08;二&#xff09;初始条件与最优策略 &#xff08;三&#xff09;证明最优策略总是将所有钱投入到单一投资产品中…...

一篇保姆式虚拟机安装ubantu教程

前言&#xff1a; 本文将介绍在VMware安装ubantu&#xff0c;会的人可以试试上一篇介绍centos/ubantu安装docker环境,不同环境安装docker。一篇保姆式centos/unbantu安装docker 官网下载iso:Ubuntu 18.04.6 LTS (Bionic Beaver) 本次使用的版本是&#xff1a; 一&…...

缓冲区的奥秘:解析数据交错的魔法

目录 一、理解缓存区的好处 &#xff08;一&#xff09;直观性的理解 &#xff08;二&#xff09;缓存区的好处 二、经典案例分析体会 &#xff08;一&#xff09;文件读写流&#xff08;File I/O Buffering&#xff09; BufferedOutputStream 和 BufferedWriter 可以加快…...

CentOS 7.9 搭建本地Yum源

yum&#xff08;Yellow Dog Updater&#xff0c;Modified&#xff09;是一个在Fedora、Centos、RedHat中的Shell前端软件包管理器。基于RPM包管理&#xff0c;能够从指定的服务器自动下载RPM包并且安装&#xff0c;可以自动处理依赖关系&#xff0c;并且一次安装所有依赖的软件…...

【Python】爬虫实战:高效爬取电影网站信息指南(涵盖了诸多学习内容)

本期目录 1 爬取思路 2 爬虫过程 2.1 网址 2.2 查看网页代码 3 爬取数据 3.1 导入包 3.2 爬取代码 01 爬取思路 \*- 第一步&#xff0c;获取页面内容\*- 第二步&#xff1a;解析并获取单个项目链接 \*- 第三步&#xff1a;获取子页面内容 \*- 第四步&#xff1a;解析…...

MATLAB和C++及Python流式细胞术

&#x1f335;MATLAB 片段 流式细胞术&#xff08;Flow Cytometry&#xff09;是一种用于分析细胞或其他颗粒悬浮在流动介质中的方法。MATLAB 可以用来处理和分析流式细胞术的数据&#xff0c;例如用于数据预处理、可视化和分析。以下是一些常见的 MATLAB 处理流式细胞术数据的…...

Vue3 pinia使用

Pinia 是一个现代的状态管理库&#xff0c;专为 Vue 3 设计。它提供了一种简单、直观的方式来管理应用中的全局状态 (就是不同组件都希望去共享的一些变量,函数等)。Pinia 的设计灵感来自于 Vuex&#xff08;Vue 2 的状态管理库&#xff09;&#xff0c;但进行了许多改进&#…...

tdengine学习笔记-建库和建表

目录 建库和建表 创建超级表​ 创建表​ 自动建表​ 创建普通表​ 多列模型 VS 单列模型​ 数据类型映射​ 示例程序汇总​ 在车联网领域的应用 1. 数据模型概述 2. 表结构设计 2.1 静态数据表 2.2 动态数据表 4. 查询数据 4.1 查询单个车辆的数据 4.2 查询多个…...

Django数据迁移出错,解决raise NodeNotFoundError问题

错误出现在&#xff1a; raise NodeNotFoundError(self.error_message, self.key, originself.origin) django.db.migrations.exceptions.NodeNotFoundError: Migration myApp.0003_alter_jobinfo_practise dependencies reference nonexistent parent node (myApp, 0002_renam…...

景联文科技:以全面数据处理服务推动AI创新与产业智能化转型

数据标注公司在人工智能领域扮演着重要角色&#xff0c;通过提供高质量的数据标注服务&#xff0c;帮助企业和组织训练和优化机器学习模型。从需求分析到数据交付&#xff0c;每一个步骤都需要严格把控&#xff0c;确保数据的质量和安全性。 景联文科技是一家专业的数据采集与标…...

MySQL学习/复习7表的内外连接

一、内连接...

Spring Cloud入门笔记2(OpenFeign)

场景&#xff1a; OpenFeign中集成了LoadBalancer,并简化了微服务调用&#xff0c;所以实际上使用该技术 技术栈&#xff1a;OpenFeign 步骤一&#xff1a;导入依赖 <!--openfeign--> <dependency><groupId>org.springframework.cloud</groupId><a…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...