跨域相关的一些问题 ✅
当网页从一个源(https://baidu.com)请求另一个源(如 https://taobao/api)的资源时,就发生了跨域。由于安全原因(防止恶意网站通过脚本访问用户在其他网站上的数据),浏览器对跨域请求设置了限制,这样的机制称为同源策略。
浏览器特有的现象
应该说,跨域不是浏览器特有的现象,跨域几乎在所有客户端都存在,但是同源策略是浏览器特有的。当你在浏览器中执行 AJAX 请求,浏览器首先会检查此请求的源是否合法(即与当前页面的源是否相同)。如果请求是跨域的,浏览器会立即阻止该请求发送(后端会连请求都收不到)。
但是微信小程序,桌面应用和APP等客户端应用是不会受到同源策略的直接限制的,因为他们运行的客户端环境并不是浏览器,但是他们需要遵守的是所处的运行环境的其他规范。比如微信小程序上线后能请求的API必须用的是https协议,而且能请求哪些域名下的API必须在后台自己的小程序管理下面进行登记 (没记错的话,上一次开发小程序至今已有一坤年) ,开发环境下倒是无所谓。
假设我在浏览器端和在微信小程序端同时发送一个请求给后端,那后端收到的请求头分别长什么样子?以下只对比一些关键字段:
1️⃣ 浏览器
- User-Agent:用来标识当前浏览器类型和版本,例如:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
- Referer:重头戏,指示请求来源的 URL,在JavaScript里面对这个字段能进行的修改极端有限,甚至可以说没有,Referer 的值是由浏览器自动设置的。
- Accept:表示浏览器可以处理的内容类型
- Cookie:如果有的话
2️⃣ 微信小程序
- User-Agent:微信小程序的请求头中的 User-Agent 会有不同的格式,通常包含 “MicroMessenger” 字样,例如:Mozilla/5.0 (Linux; Android 10; SM-G9500 Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/12.0 WeChat/8.0.0.1 MiniProgramPlatform/1.0.0.0
- Referer:微信小程序可以设置特定的 Referer,但也不是在开发过程中能够通过JavaScript来控制的,在使用
wx.request
的时候Referer由小程序框架自动填充,通常会被设置为小程序的合法请求域名,即你在小程序后台配置的接口域名 - Accept:通常为*/*
- Cookie:如果有的话
处理跨域问题(浏览器端)
CORS
首先得知道,CORS并没有直接作用于客户端,CORS配置是服务端的响应头配置,比较关键的字段是以下两个:
const responseHeaders = {"Access-Control-Allow-Origin": "*" // 允许跨域请求的域名"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS" // 允许跨域请求的方法
}
它规定了哪些方法,来自哪些域名的请求可以成功调用服务端的接口,这保护的是服务端的安全性。当浏览器发送跨域请求时,服务器通过 CORS 响应头(如 Access-Control-Allow-Origin)来告诉浏览器是否允许该请求,具体来说,服务器在返回的 HTTP 响应中添加 CORS 相关的头部信息,允许特定的源进行访问。
到目前为止,CORS的作用还是停留在对服务器的保护上,但是却抛出了一个问题💡:如果我的请求被浏览器的同源策略所拦截,我压根发不出去,更不可能知道响应头的Access-Control-Allow-Origin
到底是什么,那我的AJAX岂不一辈子都发不出去?
所以OPTIONS,预检请求登场。OPTIONS 请求是一种 HTTP 请求方法,用于查询服务器支持的 HTTP 方法及其他选项,而不是直接请求特定资源。根据 CORS 规范,预检请求通常在以下情况下发送:
1️⃣ 请求方法为 PUT、DELETE、PATCH、OPTIONS,或其他非 GET 和 POST 的方法
2️⃣ 如果 Content-Type 头为除 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 以外的任何值(例如 application/json)
3️⃣ 当请求中包含自定义头部(例如 X-Requested-With)
如果OPTIONS询问目标服务器后发现自己的接下来要发送的请求能够符合服务器那边的CORS配置,那同源策略就会放行,AJAX就能发到后端。
顺便提一嘴,开发微信小程序有时候也得后端配合设置CORS,说不定你的referer一开始没在人家的白名单里呢。
JSONP
JSONP算一种投机取巧的方法,在如果服务器是团队内部的,那还是用CORS。 JSON是不受同源策略限制的,但是这种方法只能支持GET请求而且相对不安全。 至今不知道不安全在哪,被攻击到的我觉得是服务端而不是客户端。
给一个demo,后端用了Egg:
// router.js
module.exports = (app) => {const { router, controller } = app;// JSONP 数据接口router.get('/api/data', controller.home.getData);
};// home.js
const Controller = require('egg').Controller;
class HomeController extends Controller {async getData() {const { ctx } = this;// 获取回调函数名(来自query传参数)const callback = ctx.query.callback; // 要返回的数据const data = { message: 'Hello from Egg.js!' }; // 检查是否提供了callback参数if (callback) {ctx.body = `${callback}(${JSON.stringify(data)})`; // 返回 JSONP 响应} else {ctx.body = { error: 'No callback provided' }; // 返回错误}}
}
module.exports = HomeController;
前端:
<script>function handleResponse(data) {// 处理返回的 JSONP 数据console.log(data);document.getElementById("result").innerText = data.message;}function fetchData() {const script = document.createElement("script");script.src = "http://localhost:7001/api/data?callback=handleResponse"; // 注意 CORS 端口应与后端一致document.body.appendChild(script); // 动态插入 script 标签进行 JSONP 请求}
</script>
但是这种script标签的用法和开发中用的比较多的用script来下载其他库不是一回事。
使用 script 标签发起 JSONP 请求的目的是从不同源(跨域)获取数据。服务端会以一个可调用的 JavaScript 函数的形式返回数据,以便前端能够在加载该脚本后执行回调函数来处理数据。
而用它来加载库是为了引入第三方 JavaScript 代码,以便在你的网页中使用这些库提供的功能。加载后的库通常会直接在全局范围内注册变量。
Proxy
在同源服务器上设置代理,通过中间的服务器转发请求,浏览器请求的是同源服务器,从而绕过同源策略。比较常用的是Nginx的反向代理功能,开发中Webpack和Vite都提供了开启内置的反向代理服务器的功能。
既然要浏览器请求的是同源服务器,那axios里面的url就不能是真正的API URL,而应该是前端应用的生产环境URL,然后在Nginx内做了一次转发,把请求转发到后端服务器去。这种代理和典型的反向代理。
提一嘴正向代理和方向代理。
反向代理是指客户端通过代理服务器发起请求。1️⃣ 客户端只把请求发到代理服务器 2️⃣ 代理服务器接收请求,并根据负载均衡策略或配置将请求转发给一个或多个后端服务器 3️⃣ 后端服务器处理请求后,将响应返回给反向代理服务器 4️⃣ 反向代理服务器再将响应转发回客户端。
如果说反向代理是作用于服务端,那正向代理就是作用于客户端,通常是为了匿名、绕过限制、内容过滤等,比如翻墙用的就是正向代理。了解实在有限,以后再研究研究
iframe标签
可以用iframe实现跨域请求,但是我没用过,甚至连这个标签我都用的很少。
先创建一个主页面,其中嵌入了另一个跨域的页面:
<script>function sendMessage() {const iframe = document.getElementById('myIframe');// 发送消息给 iframeiframe.contentWindow.postMessage('Hello from the main page!', '*');}window.addEventListener('message', (event) => {// 监听来自 iframe 的消息console.log('Received from iframe:', event.data);document.getElementById('result').innerText = event.data;});
</script>
<body><h1>主页面</h1><button onclick="sendMessage()">发送消息到iframe</button><div id="result"></div><iframe id="myIframe" src="https://example.com" width="600" height="400"></iframe>
</body>
再创建一个跨域页面iframe.html,必须支持接收消息和发送响应:
<script>window.addEventListener('message', (event) => {// 监听主页面发送的消息console.log('Received from main page:', event.data);const result = fetch(..........)// 发送响应回主页面event.source.postMessage('Hello from the iframe!', result);});
</script>
运行方法:
- 将主页面的 index.html 文件放在一个能够访问的 Web 服务器上。
- 将跨域页面的 iframe.html 放在另一个可以访问的地址上(务必符合跨源域)。
- 在主页面上,通过点击按钮“发送消息到 iframe”,会发送一个消息给嵌入的 iframe。
- iframe 页面接收到消息后,会回复一个消息,主页面也会接收到这个回复。
相关文章:
跨域相关的一些问题 ✅
当网页从一个源(https://baidu.com)请求另一个源(如 https://taobao/api)的资源时,就发生了跨域。由于安全原因(防止恶意网站通过脚本访问用户在其他网站上的数据),浏览器对跨域请求…...
RPC学习
一、什么是 RPC RPC(Remote Procedure Call),即远程过程调用,是一种计算机通信协议,它允许运行在一台计算机上的程序调用另一台计算机上的子程序或函数,就好像调用本地程序中的函数一样,无需程序…...
coe文件转mif(c语言)
1 mif文件格式 DEPTH=1024; --The size of data in bits WIDTH=16; --The size of memory in words ADDRESS_RADIX = DEC; --The radix for address values DATA_RADIX = UNS...

【leetcode】动态规划
31. 873. 最长的斐波那契子序列的长度 题目: 如果序列 X_1, X_2, ..., X_n 满足下列条件,就说它是 斐波那契式 的: n > 3对于所有 i 2 < n,都有 X_i X_{i1} X_{i2} 给定一个严格递增的正整数数组形成序列 arr ࿰…...

介绍一下atoi(arr);(c基础)
hi , I am 36 适合对象c语言初学者 atoi(arr);是返回整数(int型),整数是arr数组中字符中数字 格式 #include<stdio.h> atoi(arr); 返回值arr数组中的数字 未改变arr数组 #include<stdlib.h>//atoi(arr); 返 <stdlib> int main(…...

docker入门学习笔记
docker的定义 docker是一个用于构建、运行、传送 应用程序的平台。 为什么要使用docker ? 在开发测试库环境中测试成功后,打包成集装箱,到生产环境也是能够成功的。而传统的安装方式不仅繁琐,并且在测试环境安装后,到…...

使用Python和Pybind11调用C++程序(CMake编译)
目录 一、前言二、安装 pybind11三、编写C示例代码四、结合Pybind11和CMake编译C工程五、Python调用动态库六、参考 一、前言 跨语言调用能对不同计算机语言进行互补,本博客主要介绍如何实现Python调用C语言编写的函数。 实验环境: Linux gnuPython3.10…...

tableau-制作30个图表
制作条形图 步骤: 1、横轴是数值,对应了某一个度量值,纵轴是一个标签 战区的成交额,条形图横轴是战区,纵轴是成交额 下钻条形图 1、增加业务架构-战区右键点击,分层结构,增加分层结构 调整业务架构,将战区,城市,小组移动到业务架构下方 此时的条形图上方有➕号展开后…...

2024APMCM亚太杯数学建模C题【宠物行业】原创论文分享
大家好呀,从发布赛题一直到现在,总算完成了2024 年APMCM亚太地区大学生数学建模竞赛C题的成品论文。 给大家看一下目录吧: 目录 摘 要: 10 一、问题重述 14 二.问题分析 15 2.1问题一 15 2.2问题二 15 2.3问题三…...

C语言解析命令行参数
原文地址:C语言解析命令行参数 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 C语言有一个 getopt 函数,可以对命令行进行解析,下面给出一个示例,用的时候可以直接copy过去修改,很方便…...

推荐一款龙迅HDMI2.0转LVDS芯片 LT6211UX LT6211UXC
龙迅的HDMI2.0转LVDS芯片LT6211UX和LT6211UXC是两款高性能的转换器芯片,它们在功能和应用上有所差异,同时也存在一些共同点。以下是对这两款芯片的详细比较和分析: 一、LT6211UX 主要特性: HDMI2.0至LVDS和MIPI转换器。HDMI2.0输…...

libmodbus 源码学习笔记
1.核心函数_框架_数据结构 整个通信的过程 就是上面这个框架 下面就是具体过程 <1> 主设备 我们首先要初始化 我们要使用的串口 然后 设置我们要访问的哪一个设备 最后打开串口 <2>从机设备 也是我们要初始化我们的串口 然后随后立即设置我们的串口设备地址 最后…...

通用网络安全设备之【防火墙】
概念: 防火墙(Firewall),也称防护墙,它是一种位于内部网络与外部网络之间的网络安全防护系统,是一种隔离技术,允许或是限制传输的数据通过。 基于 TCP/IP 协议,主要分为主机型防火…...

Vue.js基础——贼简单易懂!!(响应式 ref 和 reactive、v-on、v-show 和 v-if、v-for、v-bind)
Vue.js是一个渐进式JavaScript框架,用于构建用户界面。它专门设计用于Web应用程序,并专注于视图层。Vue允许开发人员创建可重用的组件,并轻松管理状态和数据绑定。它还提供了一个虚拟DOM系统,用于高效地渲染和重新渲染组件。Vue以…...

Mybatis 执行存储过程,获取输出参数的值
数据库环境:SQL Server 2008 R2 存储过程 alter procedure proc_generateOuterApplyId acceptType varchar(4),acceptGroupId int,outerApplyId varchar(20) output as begin set nocount onset outerApplyId 24GD6688--select outerApplyId as …...

RAG架构类型
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

Oracle 数据库 IDENTITY 列的性能选项
在上一篇文章Oracle 数据库 IDENTITY 列中,我们介绍了Oracle IDENTITY列的基础知识。本文将介绍IDENTITY列的几个性能选项。由于IDENTITY列内部使用sequence机制,因此也等同于是sequence的性能选项。 由于sequence是递增的,在高并发时&#…...

计算(a+b)/c的值
计算(ab)/c的值 C语言代码C语言代码Java语言代码Python语言代码 💐The Begin💐点点关注,收藏不迷路💐 给定3个整数a、b、c,计算表达式(ab)/c的值,/是整除运算。 输入 输入仅一行&…...

OpenCV从入门到精通实战(八)——基于dlib的人脸关键点定位
本文使用Python库dlib和OpenCV来实现面部特征点的检测和标注。 下面是代码的主要步骤和相关的代码片段: 步骤一:导入必要的库和设置参数 首先,代码导入了必要的Python库,并通过argparse设置了输入图像和面部标记预测器的参数。…...

unity | 动画模块之卡片堆叠切换
一、预览动画 可以放很多图,可以自己往后加,可以调图片x轴和y轴间距,可以调图片飞出方向,可以调堆叠方向。 图1 图片堆叠动画预览 二、纯净代码 有粉丝问我这个效果,最近很忙,没有时间细写,先…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...