当前位置: 首页 > 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…...

你的舵机抖得厉害?可能是PWM信号配置错了!STM32定时器避坑指南(实测MG996R)

STM32舵机控制实战&#xff1a;从PWM原理到MG996R精准调参 引言 当你第一次尝试用STM32控制舵机时&#xff0c;可能会遇到这样的场景&#xff1a;按照教程配置好PWM参数&#xff0c;烧录程序后却发现舵机要么纹丝不动&#xff0c;要么疯狂抖动&#xff0c;甚至发出刺耳的噪音…...

告别格式地狱:Paperxie 如何用智能排版让本科毕业论文一键通关

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/format/typesettinghttps://www.paperxie.cn/format/typesetting 当毕业论文写到最后&#xff0c;你是否也陷入过这样的困境&#xff1a;明明内容已经打磨完成&#xff0c;却…...

探索 COMSOL 三维多孔介质建模的魅力

comsol三维多孔介质 COMSOL三维多孔介质。 1.孔隙率孔径可控 2.一键区分固相孔相&#xff0c;简单方便 3.可设置五种粒径不同&#xff0c;含量不同的颗粒。嘿&#xff0c;各位科研和工程领域的小伙伴们&#xff01;今天咱们来聊聊 COMSOL 里的三维多孔介质建模&#xff0c;这玩…...

nlp_structbert_sentence-similarity_chinese-large保姆级教程:前端React界面二次开发与定制化UI集成指南

nlp_structbert_sentence-similarity_chinese-large保姆级教程&#xff1a;前端React界面二次开发与定制化UI集成指南 1. 引言&#xff1a;为什么需要定制化UI&#xff1f; 如果你已经体验过基于StructBERT-Large的语义相似度工具&#xff0c;可能会发现它的基础界面虽然功能…...

使用 Java 泛型创建 CSV 到对象的转换器

本文将介绍如何使用它 Java 创建一个通用的泛型 CSV 文件到 Java 对象转换器。通过泛型&#xff0c;我们可以避免为每个需要转换的类别编写重复的代码&#xff0c;以实现代码的重用和简化。本文将提供示例代码&#xff0c;并讨论一些关于代码设计和最佳实践的建议&#xff0c;以…...

什么是绿色软件?免安装版就是绿色软件吗?

什么是绿色软件&#xff1f;免安装版就是绿色软件吗&#xff1f;古有流氓软件耍流氓&#xff0c;今有绿色软件未必真绿色。 --马彪一、什么是绿色软件&#xff1f; 绿色软件&#xff08;Portable Software&#xff09;就是指无需安装&#xff0c;且运行过程中不向运行目录之…...

Llama-3.2V-11B-cot效果展示:‘打字机式’CoT推演过程动态演示

Llama-3.2V-11B-cot效果展示&#xff1a;‘打字机式’CoT推演过程动态演示 1. 项目概述 Llama-3.2V-11B-cot是基于Meta Llama-3.2V-11B多模态大模型开发的高性能视觉推理工具。这款工具针对双卡RTX 4090环境进行了深度优化&#xff0c;特别修复了视觉权重加载的关键Bug&#…...

HY-Motion 1.0在元宇宙中的应用:虚拟世界角色动画生成

HY-Motion 1.0在元宇宙中的应用&#xff1a;虚拟世界角色动画生成 1. 元宇宙里&#xff0c;角色为什么需要“活”起来 打开一个元宇宙应用&#xff0c;你看到的可能是一个精致的虚拟空间&#xff0c;但真正让人愿意停留的&#xff0c;从来不是静态的场景&#xff0c;而是能动…...

页游党必看!传奇、篮球、策略全都有,点击即玩

对于喜欢玩网页游戏的朋友来说&#xff0c;找一个靠谱、福利多、游戏全的平台太重要了&#xff01;不用下载、点击即玩&#xff0c;还能安心挂机不担心跑路&#xff0c;这样的平台才是真刚需&#xff5e; 今天就给大家安利一个深耕页游十余载的老牌平台——602游戏平台&#x…...

OpenClaw技能扩展指南:为nanobot添加自定义QQ机器人功能

OpenClaw技能扩展指南&#xff1a;为nanobot添加自定义QQ机器人功能 1. 为什么需要QQ机器人集成 去年夏天&#xff0c;我发现自己经常在深夜调试代码时&#xff0c;需要反复切换手机和电脑查看运行结果。这种低效的操作让我开始寻找一种更优雅的解决方案——通过聊天工具直接…...