跨域相关的一些问题 ✅
当网页从一个源(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 图片堆叠动画预览 二、纯净代码 有粉丝问我这个效果,最近很忙,没有时间细写,先…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

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

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...

算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...

GAN模式奔溃的探讨论文综述(一)
简介 简介:今天带来一篇关于GAN的,对于模式奔溃的一个探讨的一个问题,帮助大家更好的解决训练中遇到的一个难题。 论文题目:An in-depth review and analysis of mode collapse in GAN 期刊:Machine Learning 链接:...