一切都始于一个错误
在 JavaScript 和 Node.js 中使用 URL 应该很简单,但是我们项目中最近的一个错误让我陷入了 URL 和 URLSearchParams API 中微妙怪癖的兔子洞。这篇文章将探讨这些怪癖,它们如何在您的代码中引起问题,以及您可以采取哪些措施来避免它们。
问题:使用 Axios 处理 URL
我们在生成 URL 并向其添加哈希签名时遇到了此问题。查询参数的百分比编码不一致,导致意外行为和错误的哈希签名。
很明显,URL 和 URLSearchParams 对象之间的交互需要格外小心。
陷阱#1:URL.search 与 URLSearchParams.toString()
第一个惊喜是 URL.search 和 URLSearchParams.toString() 之间的区别。
使用 .searchParams 修改 URL 时要小心,因为根据 WHATWG 规范,URLSearchParams 对象使用不同的规则来确定要对哪些字符进行百分比编码。例如,URL 对象不会对 ASCII 波形符 (~) 字符进行百分号编码,而 URLSearchParams 将始终对其进行编码。
// Example 1 const url = new URL("https://example.com?param=foo bar"); console.log(url.search); // prints param=foo%20bar console.log(url.searchParams.toString()); // prints ?param=foo+bar // Example 2 const myURL = new URL('https://example.org/abc?foo=~bar'); console.log(myURL.search); // prints ?foo=~bar // Modify the URL via searchParams... myURL.searchParams.sort(); console.log(myURL.search); // prints ?foo=%7Ebar
在我们的项目中,我们需要显式地重新分配 url.search = url.searchParams.toString() 以确保查询字符串的编码一致。
陷阱#2:加号困境
另一个问题是 URLSearchParams 如何处理字符。默认情况下,URLSearchParams 解释为空格,这在编码二进制数据或 Base64 字符串时可能会导致数据损坏。
const params = new URLSearchParams("bin=E+AXQB+A"); console.log(params.get("bin")); // "E AXQB A"
一种解决方案是在将值附加到 URLSearchParams 之前使用encodeURIComponent:
params.append("bin", encodeURIComponent("E+AXQB+A"));
更多详细信息请参阅 MDN 文档。
陷阱 #3:URLSearchParams.get 与 URLSearchParams.toString()
比较 URLSearchParams.get 和 URLSearchParams.toString 的输出时会出现另一个微妙之处。例如:
const params = new URLSearchParams("?key=value&key=other"); console.log(params.get("key")); // "value" (first occurrence) console.log(params.toString()); // "key=value&key=other" (all occurrences serialized)
在多值场景中,get 仅返回第一个值,而 toString 则序列化所有值。
我们代码库中的修复
在我们的项目中,我们通过显式重新分配搜索属性解决了该问题:
url.search = url.searchParams.toString(); url.searchParams.set( "hash", cryptography.createSha256HmacBase64UrlSafe(url.href, SECRET_KEY ?? "") );
这确保了在添加哈希值之前所有查询参数都已正确编码。
Node.js 查询字符串模块
WHATWG URLSearchParams 接口和 querystring 模块具有类似的用途,但 querystring 模块的用途更通用,因为它允许自定义分隔符(& 和 =)。另一方面,URLSearchParams API 纯粹是为 URL 查询字符串而设计的。
querystring 比 URLSearchParams 性能更高,但不是标准化 API。当性能不重要或需要与浏览器代码兼容时,请使用 URLSearchParams。
与 querystring 模块不同,使用 URLSearchParams 时,不允许数组值形式的重复键。数组使用 array.toString() 进行字符串化,它只是用逗号连接所有数组元素。
// Example 1 const url = new URL("https://example.com?param=foo bar"); console.log(url.search); // prints param=foo%20bar console.log(url.searchParams.toString()); // prints ?param=foo+bar // Example 2 const myURL = new URL('https://example.org/abc?foo=~bar'); console.log(myURL.search); // prints ?foo=~bar // Modify the URL via searchParams... myURL.searchParams.sort(); console.log(myURL.search); // prints ?foo=%7Ebar
使用querystring模块,查询字符串'foo=bar&abc=xyz&abc=123'被解析为:
const params = new URLSearchParams("bin=E+AXQB+A"); console.log(params.get("bin")); // "E AXQB A"
要点
小心 URLSearchParams 处理特殊字符(例如 ~)和空格。必要时使用encodeURIComponent。
了解 URL.search、URLSearchParams.get 和 URLSearchParams.toString 之间的区别,以避免意外行为。
在 Node.js 中,如果要将重复的查询参数键解析为数组,请使用查询字符串模块。
以上是JavaScript 中 URL 和 URLSearchParams 的陷阱的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

本文讨论了使用浏览器开发人员工具的有效JavaScript调试,专注于设置断点,使用控制台和分析性能。

将矩阵电影特效带入你的网页!这是一个基于著名电影《黑客帝国》的酷炫jQuery插件。该插件模拟了电影中经典的绿色字符特效,只需选择一张图片,插件就会将其转换为充满数字字符的矩阵风格画面。快来试试吧,非常有趣! 工作原理 插件将图片加载到画布上,读取像素和颜色值: data = ctx.getImageData(x, y, settings.grainSize, settings.grainSize).data 插件巧妙地读取图片的矩形区域,并利用jQuery计算每个区域的平均颜色。然后,使用

本文将引导您使用jQuery库创建一个简单的图片轮播。我们将使用bxSlider库,它基于jQuery构建,并提供许多配置选项来设置轮播。 如今,图片轮播已成为网站必备功能——一图胜千言! 决定使用图片轮播后,下一个问题是如何创建它。首先,您需要收集高质量、高分辨率的图片。 接下来,您需要使用HTML和一些JavaScript代码来创建图片轮播。网络上有很多库可以帮助您以不同的方式创建轮播。我们将使用开源的bxSlider库。 bxSlider库支持响应式设计,因此使用此库构建的轮播可以适应任何

数据集对于构建API模型和各种业务流程至关重要。这就是为什么导入和导出CSV是经常需要的功能。在本教程中,您将学习如何在Angular中下载和导入CSV文件

核心要点 利用 JavaScript 增强结构化标记可以显着提升网页内容的可访问性和可维护性,同时减小文件大小。 JavaScript 可有效地用于为 HTML 元素动态添加功能,例如使用 cite 属性自动在块引用中插入引用链接。 将 JavaScript 与结构化标记集成,可以创建动态用户界面,例如无需页面刷新的选项卡面板。 确保 JavaScript 增强功能不会妨碍网页的基本功能至关重要;即使禁用 JavaScript,页面也应保持功能正常。 可以使用高级 JavaScript 技术(


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 Linux新版
SublimeText3 Linux最新版

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),