Whiz Tools

URL 字符串转义器

URL 字符串转义工具

介绍

在网络开发和互联网通信领域,URL(统一资源定位符)在识别网络资源方面起着至关重要的作用。然而,URL 对它们可以包含的字符有一定的限制。某些字符具有特殊含义,而其他字符由于在传输过程中可能被误解或损坏,因此不适合在 URL 中使用。

URL 编码,也称为百分号编码,是一种将特殊字符转换为可以通过互联网传输的格式的机制。该工具允许您输入一个 URL 字符串并转义特殊字符,确保 URL 是有效的,并且可以被网络浏览器和服务器正确解释。

理解 URL 编码

什么是 URL 编码?

URL 编码涉及将不安全的 ASCII 字符替换为 % 后跟两个十六进制数字,表示字符的 ASCII 码。这确保了信息在互联网上传输时不会被更改。

例如,空格字符 ' ' 被替换为 %20

为什么需要 URL 编码?

URL 只能使用 ASCII 字符集通过互联网发送。由于 URL 通常包含超出该集合的字符,因此必须将其转换为有效的 ASCII 格式。URL 编码确保特殊字符不会导致意外效果或网络请求中的错误。

需要编码的字符

根据 RFC 3986 规范,以下字符在 URL 中是保留的,必须进行百分号编码才能字面使用:

  • 一般分隔符: :, /, ?, #, [, ], @
  • 子分隔符: !, $, &, ', (, ), *, +, ,, ;, =

此外,任何非 ASCII 字符,包括 Unicode 字符,都必须编码。

URL 编码是如何工作的?

编码过程

  1. 识别特殊字符: 解析 URL 字符串并识别不属于未保留的 ASCII 字符(字母、数字、-._~)的字符。

  2. 转换为 ASCII 码: 对于每个特殊字符,获取其 ASCII 或 Unicode 码点。

  3. 转换为 UTF-8 字节序列(如有必要): 对于非 ASCII 字符,使用 UTF-8 编码将字符编码为一个或多个字节。

  4. 转换为十六进制: 将每个字节转换为其两位十六进制等价物。

  5. 前缀百分号: 在每个十六进制字节前加上 % 符号。

示例编码

  • 字符: ' '(空格)

    • ASCII 码: 32
    • 十六进制: 20
    • URL 编码: %20
  • 字符: 'é'

    • UTF-8 编码: 0xC3 0xA9
    • URL 编码: %C3%A9

需要考虑的边缘情况

  • Unicode 字符: 非 ASCII 字符必须以 UTF-8 编码,然后进行百分号编码。

  • 已经编码的百分号: 作为百分号编码的一部分的百分号不能被重新编码。

  • 查询字符串中的保留字符: 某些字符在查询字符串中具有特殊含义,应进行编码以防止更改结构。

URL 解码

什么是 URL 解码?

URL 解码是 URL 编码的反向过程。它将百分号编码的字符转换回其原始形式,使 URL 对人类和系统可读和可解释。

解码过程

  1. 识别百分号编码序列: 在 URL 字符串中定位所有 % 符号后跟两个十六进制数字。

  2. 将十六进制转换为字节: 将每个十六进制值转换为其对应的字节。

  3. 解码 UTF-8 字节(如有必要): 对于多字节序列,组合字节并使用 UTF-8 编码解码以获得原始字符。

  4. 替换编码序列: 用解码的字符替换百分号编码序列。

示例解码

  • 编码: hello%20world

    • %20 转换为空格 ' '
    • 解码: hello world
  • 编码: J%C3%BCrgen

    • %C3%A4 转换为 UTF-8 中的 'ü'
    • 解码: Jürgen

URL 解码的重要性

在处理来自 URL 的用户输入、读取查询参数或解释从网络请求接收到的数据时,URL 解码是必不可少的。它确保从 URL 中提取的信息处于其正确的、预期的形式。

用例

网络开发

  • 查询参数: 编码查询参数中的用户输入以防止错误或安全漏洞。

  • 路径参数: 安全地将动态数据包含在 URL 路径中。

数据传输

  • API 和 Web 服务: 确保发送到 API 的数据格式正确。

  • 国际化: 支持包含各种语言字符的 URL。

安全性

  • 防止注入攻击: 编码输入以降低跨站脚本(XSS)和其他注入攻击的风险。

替代方案

虽然 URL 编码是必需的,但在某些情况下,其他编码方法可能更合适:

  • Base64 编码: 用于在 URL 中编码二进制数据或在需要更高信息密度时。

  • 不带百分号编码的 UTF-8 编码: 某些系统直接使用 UTF-8 编码,但如果处理不当,可能会导致问题。

根据您的应用程序的具体情况选择最合适的编码方法。

历史

URL 编码是在 1990 年代 URL 和 URI(统一资源标识符)标准的早期规范中引入的。由于全球使用的多样化系统和字符集,产生了一种一致的方式来编码特殊字符的需求。

关键里程碑包括:

  • RFC 1738(1994): 定义了 URL 并引入了百分号编码。

  • RFC 3986(2005): 更新了 URI 语法,完善了编码规则。

随着时间的推移,URL 编码已成为网络技术的一个组成部分,确保了不同系统和平台之间的可靠通信。

代码示例

以下是如何在各种编程语言中执行 URL 编码的示例:

' Excel VBA 示例
Function URLEncode(ByVal Text As String) As String
    Dim i As Integer
    Dim CharCode As Integer
    Dim Char As String
    Dim EncodedText As String

    For i = 1 To Len(Text)
        Char = Mid(Text, i, 1)
        CharCode = AscW(Char)
        Select Case CharCode
            Case 48 To 57, 65 To 90, 97 To 122, 45, 46, 95, 126 ' 0-9, A-Z, a-z, -, ., _, ~
                EncodedText = EncodedText & Char
            Case Else
                If CharCode < 0 Then
                    ' 处理 Unicode 字符
                    EncodedText = EncodedText & "%" & Hex(65536 + CharCode)
                Else
                    EncodedText = EncodedText & "%" & Right("0" & Hex(CharCode), 2)
                End If
        End Select
    Next i
    URLEncode = EncodedText
End Function

' 用法:
' =URLEncode("https://example.com/?name=Jürgen")
% MATLAB 示例
function encodedURL = urlEncode(url)
    import java.net.URLEncoder
    encodedURL = char(URLEncoder.encode(url, 'UTF-8'));
end

% 用法:
% encodedURL = urlEncode('https://example.com/?name=Jürgen');
## Ruby 示例
require 'uri'

url = 'https://example.com/path?query=hello world&name=Jürgen'
encoded_url = URI::DEFAULT_PARSER.escape(url)
puts encoded_url
## 输出: https://example.com/path?query=hello%20world&name=J%C3%BCrgen
// Rust 示例
use url::form_urlencoded;

fn main() {
    let url = "https://example.com/path?query=hello world&name=Jürgen";
    let encoded_url = percent_encode(url);
    println!("{}", encoded_url);
    // 输出: https://example.com/path%3Fquery%3Dhello%20world%26name%3DJ%C3%BCrgen
}

fn percent_encode(input: &str) -> String {
    use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
    utf8_percent_encode(input, NON_ALPHANUMERIC).to_string()
}
## Python 示例
import urllib.parse

url = 'https://example.com/path?query=hello world&name=Jürgen'
encoded_url = urllib.parse.quote(url, safe=':/?&=')
print(encoded_url)
## 输出: https://example.com/path?query=hello%20world&name=J%C3%BCrgen
// JavaScript 示例
const url = 'https://example.com/path?query=hello world&name=Jürgen';
const encodedURL = encodeURI(url);
console.log(encodedURL);
// 输出: https://example.com/path?query=hello%20world&name=J%C3%BCrgen
// Java 示例
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public class URLEncodeExample {
    public static void main(String[] args) throws Exception {
        String url = "https://example.com/path?query=hello world&name=Jürgen";
        String encodedURL = URLEncoder.encode(url, StandardCharsets.UTF_8.toString());
        // 将 "+" 替换为 "%20" 表示空格
        encodedURL = encodedURL.replace("+", "%20");
        System.out.println(encodedURL);
        // 输出: https%3A%2F%2Fexample.com%2Fpath%3Fquery%3Dhello%20world%26name%3DJ%C3%BCrgen
    }
}
// C# 示例
using System;
using System.Net;

class Program
{
    static void Main()
    {
        string url = "https://example.com/path?query=hello world&name=Jürgen";
        string encodedURL = Uri.EscapeUriString(url);
        Console.WriteLine(encodedURL);
        // 输出: https://example.com/path?query=hello%20world&name=J%C3%BCrgen
    }
}
<?php
// PHP 示例
$url = 'https://example.com/path?query=hello world&name=Jürgen';
$encodedURL = urlencode($url);
echo $encodedURL;
// 输出: https%3A%2F%2Fexample.com%2Fpath%3Fquery%3Dhello+world%26name%3DJ%C3%BCrgen
?>
// Go 示例
package main

import (
    "fmt"
    "net/url"
)

func main() {
    urlStr := "https://example.com/path?query=hello world&name=Jürgen"
    encodedURL := url.QueryEscape(urlStr)
    fmt.Println(encodedURL)
    // 输出: https%3A%2F%2Fexample.com%2Fpath%3Fquery%3Dhello+world%26name%3DJ%25C3%25BCrgen
}
// Swift 示例
import Foundation

let url = "https://example.com/path?query=hello world&name=Jürgen"
if let encodedURL = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
    print(encodedURL)
    // 输出: https://example.com/path?query=hello%20world&name=J%C3%BCrgen
}
## R 示例
url <- "https://example.com/path?query=hello world&name=Jürgen"
encodedURL <- URLencode(url, reserved = TRUE)
print(encodedURL)
## 输出: https://example.com/path?query=hello%20world&name=J%C3%BCrgen

注意: 输出可能会根据每种语言如何处理保留字符和空格(例如,将空格编码为 %20+)而略有不同。

URL 编码过程的 SVG 图示

URL 编码过程 原始 URL 识别特殊 字符 编码 URL 示例: 输入: https://example.com/über uns 输出: https://example.com/%C3%BCber%20uns

安全考虑

适当的 URL 编码和解码对安全至关重要:

  • 防止注入攻击: 编码用户输入有助于防止恶意代码被执行,从而降低跨站脚本(XSS)和 SQL 注入的风险。

  • 数据完整性: 确保数据在传输过程中不会被更改或损坏。

  • 遵守标准: 遵循编码标准可以避免系统之间的互操作性问题。

参考文献

  1. RFC 3986 - 统一资源标识符(URI): https://tools.ietf.org/html/rfc3986
  2. 什么是 URL 编码以及它是如何工作的? https://www.urlencoder.io/learn/
  3. 百分号编码: https://en.wikipedia.org/wiki/Percent-encoding
  4. URL 标准: https://url.spec.whatwg.org/
  5. URI.escape 已过时: https://stackoverflow.com/questions/2824126/why-is-uri-escape-deprecated

结论

URL 编码是网络开发和互联网通信的重要方面。通过将特殊字符转换为安全格式,它确保 URL 被浏览器和服务器正确解释,从而维护数据传输的完整性和安全性。该工具提供了一种方便的方式来转义 URL 中的特殊字符,增强兼容性并防止潜在的错误或安全漏洞。

反馈