Sử dụng JSON.decode
cho mục đích này đi kèm với những hạn chế đáng kể mà bạn phải biết:
- Bạn phải đặt chuỗi trong dấu ngoặc kép
- Nhiều ký tự không được hỗ trợ và phải tự thoát ra. Ví dụ, đi qua bất kỳ những điều sau đây để
JSON.decode
(sau khi gói chúng trong dấu ngoặc kép) sẽ báo lỗi mặc dù đây là những bài hợp lệ: \\n
, \n
, \\0
,a"a
- Nó không hỗ trợ thoát hệ thập lục phân:
\\x45
- Nó không hỗ trợ chuỗi điểm mã Unicode:
\\u{045}
Cũng có những lưu ý khác. Về cơ bản, sử dụng JSON.decode
cho mục đích này là một cuộc tấn công và không hoạt động theo cách bạn có thể mong đợi. Bạn nên gắn bó với việc sử dụng JSON
thư viện để xử lý JSON, không phải cho các hoạt động chuỗi.
Gần đây tôi đã tự mình gặp phải vấn đề này và muốn có một bộ giải mã mạnh mẽ, vì vậy tôi đã tự viết một bộ. Nó đã hoàn chỉnh và được kiểm tra kỹ lưỡng và có sẵn tại đây: https://github.com/iansan5653/unraw . Nó bắt chước tiêu chuẩn JavaScript càng gần càng tốt.
Giải trình:
Nguồn có khoảng 250 dòng vì vậy tôi sẽ không bao gồm tất cả ở đây, nhưng về cơ bản nó sử dụng Regex sau đây để tìm tất cả các chuỗi thoát và sau đó phân tích cú pháp chúng bằng cách sử dụng parseInt(string, 16)
để giải mã các số cơ số 16 và sau đó String.fromCodePoint(number)
để lấy ký tự tương ứng:
/\\(?:(\\)|x([\s\S]{0,2})|u(\{[^}]*\}?)|u([\s\S]{4})\\u([^{][\s\S]{0,3})|u([\s\S]{0,4})|([0-3]?[0-7]{1,2})|([\s\S])|$)/g
Đã nhận xét (LƯU Ý: regex này khớp với tất cả các chuỗi thoát, bao gồm cả những chuỗi không hợp lệ. Nếu chuỗi sẽ gây ra lỗi trong JS, nó sẽ tạo ra lỗi trong thư viện của tôi [tức là '\x!!'
sẽ lỗi]):
/
\\ # All escape sequences start with a backslash
(?: # Starts a group of 'or' statements
(\\) # If a second backslash is encountered, stop there (it's an escaped slash)
| # or
x([\s\S]{0,2}) # Match valid hexadecimal sequences
| # or
u(\{[^}]*\}?) # Match valid code point sequences
| # or
u([\s\S]{4})\\u([^{][\s\S]{0,3}) # Match surrogate code points which get parsed together
| # or
u([\s\S]{0,4}) # Match non-surrogate Unicode sequences
| # or
([0-3]?[0-7]{1,2}) # Match deprecated octal sequences
| # or
([\s\S]) # Match anything else ('.' doesn't match newlines)
| # or
$ # Match the end of the string
) # End the group of 'or' statements
/g # Match as many instances as there are
Thí dụ
Sử dụng thư viện đó:
import unraw from "unraw";
let step1 = unraw('http\\u00253A\\u00252F\\u00252Fexample.com');
let step2 = decodeURIComponent(step1);