共计 4433 个字符,预计需要花费 12 分钟才能阅读完成。
笔者最近三年始终在 SAP 中国研究院负责 Angular 利用开发程序员的职位,负责的产品是 SAP 电商云 Spartacus UI 的开发。Spartacus 是 SAP 公司主导的一个开源我的项目,Github 我的项目地址:https://github.com/SAP/spartacus.
电商云 Storefront UI 界面如下,客户如果想在下面下单,须要点击 Sign In / Register 进行用户注册或者登录。
因为电商云是一款面向企业级用户的产品,不少客户在施行的过程中,抉择将 SAP Customer Data Cloud(简称 CDC) 接入电商云的用户登录认证模块。CDC 容许企业轻松施行繁多登录(Single Sign-On,SSO)以提供无缝的用户体验。用户只需一次登录即可拜访多个企业应用程序。
除了 SSO 之外,CDC 还反对通过社交媒体账户进行登录,如 Facebook、Google 或 LinkedIn. 这简化了用户注册流程,进步了转化率。
问题形容和剖析
客户反映网站登录时,很少可能一次登录胜利:应用 SSO 登录时,login 按钮往往要反复点好几次才可能实现失常的网站登录。
咱们接到这个 incident 之后,在 Chrome 开发者工具的 network 面板里察看,发现 login 按钮点击之后,发送的 HTTP Post 申请,收到了 400 谬误:
这个 HTTP Post 申请的作用,是通过从 SAP CDC 颁发的 UID 和 UIDSignature,发送到 SAP Commerce Cloud authorization server endpoint 去换取 access token.
咱们逐个察看引起 HTTP 400 谬误的申请 Payload,发现 UIDSignature 这个字段里,蕴含了一个非凡的 =
字符。
这个非凡的 =
被浏览器传递到后盾后,就变成了一个空白字符。这导致了整个 authorization 申请不再无效,因而后盾返回了 HTTP 400 谬误。
解决方案
既然搞清了问题的前因后果,解决方案也就不难找到了。
这个 incident 的修复代码在这个 Pull Request 里:
能够看到,咱们在 UIDSignature
字段值传递到后盾时,增加了 encodeURIComponent
函数进行 encode
解决。
什么是 encodeURIComponent 函数?
encodeURIComponent
是 JavaScript 中的一个内置函数,用于将字符串中的特殊字符进行编码,以便可能在 URL 中传递或嵌入到 HTML 文档中。它的作用是将字符串中的非平安字符转换为平安的 URL 编码,这些非平安字符包含空格、标点符号、特殊符号等。
encodeURIComponent
的语法如下:
encodeURIComponent(uriComponent)
其中,uriComponent
是要进行编码的字符串。函数会返回一个新的字符串,其中的特殊字符都被替换成了特定的编码值,以确保 URL 的有效性和完整性。
为什么须要 encodeURIComponent?
在 HTTP 交互中,数据的传输通常波及到 URL,包含 URL 参数、门路和查问字符串等。URL 是一种蕴含特殊字符的文本,而 HTTP 协定要求 URL 必须是无效的、符合规范的。如果 URL 中蕴含特殊字符而未通过编码,就会导致各种问题,包含:
- URL 不符合规范,可能会导致申请失败或被服务器回绝。
- 数据传输的完整性可能会受到破坏,因为特殊字符可能被谬误地解释或截断。
- 安全性问题,未编码的 URL 可能会被用于攻打,例如跨站脚本(XSS)攻打。
为了防止这些问题,encodeURIComponent
函数成为了一个必不可少的工具,它确保了 URL 中的所有字符都被正确编码,以便平安地传输数据。
encodeURIComponent
的应用示例
为了更好地了解 encodeURIComponent
的必要性,咱们通过一些示例来演示它在 HTTP 交互中的利用。
1. URL 参数传递
假如咱们有一个搜寻性能,用户能够输出关键字进行搜寻。用户输出的关键字可能蕴含特殊字符,如空格、问号、和号等。为了将关键字作为 URL 参数传递给服务器,咱们须要应用 encodeURIComponent
对其进行编码。
const userInput = "Angular 2+ Tutorial?";
// 编码用户输出
const encodedKeyword = encodeURIComponent(userInput);
// 构建 URL
const searchURL = `https://example.com/search?keyword=${encodedKeyword}`;
// 发送申请
// 此时 searchURL 是平安且无效的 URL
在这个示例中,用户输出的关键字蕴含空格和问号,这些字符都不适宜间接放在 URL 中。通过应用 encodeURIComponent
,咱们将用户输出平安地编码为 URL 参数,确保了 URL 的有效性和完整性。
2. HTML 表单提交
在 HTML 表单中,用户能够输出各种字符,包含特殊字符。当用户提交表单数据时,表单数据通常会被编码并以 HTTP POST 或 GET 申请的形式发送到服务器。如果不应用encodeURIComponent
对表单数据进行编码,可能会导致数据传输问题。
<form action="https://example.com/submit" method="post">
<input type="text" name="username" value="John Doe">
<input type="text" name="email" value="john.doe@example.com">
<input type="submit" value="Submit">
</form>
在下面的表单中,如果用户在输入框中输出蕴含空格或其余特殊字符的内容,这些字符须要进行编码,以确保表单数据可能正确传输到服务器。
3. AJAX 申请
在应用 JavaScript 进行 AJAX 申请时,encodeURIComponent
也十分有用。当应用 fetch
或 XMLHttpRequest
发送数据时,特地是发送 POST 申请时,须要确保申请体中的数据是通过编码的。
username: "John Doe",
email: "john.doe@example.com"
};
// 将 JavaScript 对象转换为 URL 编码的字符串
const encodedData = Object.keys(data)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`)
.join("&");
fetch("https://example.com/submit", {
method: "POST",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
body: encodedData
});
在这个示例中,咱们将 JavaScript 对象编码为 URL 编码的字符串,并将其作为 POST 申请的申请体发送到服务器。这确保了数据的完整性和有效性。
encodeURIComponent
的编码规定
理解 encodeURIComponent
的编码规定对于正确应用它十分重要。该函数遵循一些根本的规定来确保编码后的字符串是无效的 URL 组件。
以下是 encodeURIComponent
的编码规定:
- 字母和数字以及
-
、_
、.
和~
字符不会被编码。它们放弃不变。 - 其余字符都会被编码成
%
后跟两位十六进制数字。例如,空格会被编码为%20
,问号会被编码为%3F
。 encodeURIComponent
不会编码常见的 URL 保留字符,如:
、/
、?
、&
等。这些字符在 URL 中具备非凡的含意,不应该被编码。- 如果
encodeURIComponent
函数的参数不是字符串类型,它会将参数转换为字符串,而后再进行编码。
当初,让咱们通过一些示例来演示 encodeURIComponent
的编码规定:
const originalString = "Hello, World!";
const encodedString = encodeURIComponent(originalString);
console.log(encodedString); // 输入 "Hello%2C%20World%21"
在这个示例中,逗号和空格被正确编码为 %2C
和 %20
,而叹号放弃不变。
encodeURIComponent
与encodeURI
的区别
除了 encodeURIComponent
之外,JavaScript 还提供了另一个编码函数encodeURI
。这两者有一些区别,因而在应用它们时须要留神。
encodeURI
用于编码整个 URL,而不是 URL 的一部分。它不会对常见的 URL 保留字符进行编码,包含:
、/
、?
、&
等。这意味着咱们能够应用encodeURI
来编码整个 URL,而不必放心毁坏 URL 构造。encodeURIComponent
用于编码 URL 中的组件,例如查问字符串参数的值。它会对所有非平安字符进行编码,包含常见的 URL 保留字符。这使得它非常适合用于编码查问字符串参数,以确保数据的完整性。
咱们通过示例来看看这两个函数之间的区别:
const url = "https://example.com/search?q=JavaScript & Angular";
const encodedURL = encodeURI(url);
const encodedComponent = encodeURIComponent(url);
console.log(encodedURL);
// 输入 "https://example.com/search?q=JavaScript%20&%20Angular"
console.log(encodedComponent);
// 输入 "https%3A%2F%2Fexample.com%2Fsearch%3Fq%3DJavaScript%20%26%20Angular"
在这个示例中,encodeURI
只对 URL 中的空格进行了编码,而encodeURIComponent
对整个 URL 进行了编码,包含保留字符。
总结
encodeURIComponent
是 HTTP 交互中不可或缺的工具之一,它用于将字符串中的特殊字符编码为合乎 URL 标准的平安字符串。通过确保数据的有效性和安全性,encodeURIComponent
有助于防止各种潜在的问题,包含 URL 的有效性、数据传输的完整性和安全性破绽。
在构建 URL、解决用户输出、发送 JSON 数据等 HTTP 交互场景中,正确应用encodeURIComponent
是一种良好的编程实际,有助于构建安全可靠的 Web 应用程序。在编写 Web 应用程序时,请始终记住应用 encodeURIComponent
来解决蕴含特殊字符的数据,以确保数据的安全性和有效性。