2009-02-24 14 views
67

Tôi đang viết một webservice sử dụng json để đại diện cho các tài nguyên của nó, và tôi có chút suy nghĩ về cách tốt nhất để mã hóa json. Đọc các json rfc (http://www.ietf.org/rfc/rfc4627.txt) rõ ràng là mã hóa ưa thích là utf-8. Nhưng rfc cũng mô tả một cơ chế thoát chuỗi để chỉ định các ký tự. Tôi giả định điều này thường được sử dụng để thoát khỏi các ký tự không phải ascii, do đó làm cho kết quả ascii utf-8 hợp lệ.Mã hóa ký tự JSON - UTF-8 có được hỗ trợ tốt bởi trình duyệt hay tôi nên sử dụng chuỗi thoát số?

Vì vậy, giả sử tôi có chuỗi json chứa ký tự unicode (mã-điểm) không phải là ascii. Liệu webservice của tôi chỉ cần mã hóa utf-8 và trả về nó, hay nó nên thoát khỏi tất cả những ký tự không phải ascii đó và trả về ascii thuần túy?

Tôi muốn các trình duyệt có thể thực hiện kết quả bằng cách sử dụng jsonp hoặc eval. Điều đó có ảnh hưởng đến quyết định không? Kiến thức của tôi về hỗ trợ javascript của trình duyệt khác nhau cho utf-8 là thiếu.

EDIT: Tôi muốn làm rõ rằng mối quan tâm chính của tôi về cách mã hóa kết quả thực sự là về việc xử lý kết quả trình duyệt. Những gì tôi đã đọc chỉ ra rằng các trình duyệt có thể nhạy cảm với mã hóa khi sử dụng JSONP nói riêng. Tôi đã không tìm thấy bất kỳ thông tin thực sự tốt về chủ đề, vì vậy tôi sẽ phải bắt đầu làm một số thử nghiệm để xem những gì sẽ xảy ra. Lý tưởng nhất là tôi chỉ muốn thoát khỏi vài ký tự được yêu cầu và chỉ utf-8 mã hóa kết quả.

Trả lời

63

Tất cả các trình phân tích cú pháp JSON có thể xử lý đúng UTF-8 cũng như các yêu cầu kỹ thuật JSON.

Khả năng mã hóa JSON sử dụng chuỗi thoát số thay vì chỉ cung cấp cho bạn nhiều lựa chọn hơn. Một lý do bạn có thể chọn chuỗi thoát số sẽ là nếu cơ chế vận chuyển ở giữa bộ mã hóa của bạn và bộ giải mã dự định không an toàn nhị phân.

Một lý do bạn có thể trình tự thoát số là để ngăn chặn một số nhân vật xuất hiện trong dòng, chẳng hạn như <, &", có thể được hiểu là chuỗi HTML nếu mã JSON được đặt mà không cần thoát sang HTML hoặc một trình duyệt không đúng diễn giải nó dưới dạng HTML. Điều này có thể là một biện pháp phòng ngừa chống lại việc chèn HTML hoặc tập lệnh cross-site (lưu ý: một số ký tự PHẢI được thoát trong JSON, bao gồm "\).

Một số khung công tác, bao gồm việc triển khai JSON của PHP, luôn luôn thực hiện chuỗi thoát số ở phía bộ mã hóa cho bất kỳ ký tự nào ngoài ASCII. Điều này là dành cho khả năng tương thích tối đa với cơ chế vận chuyển hạn chế và tương tự. Tuy nhiên, điều này không nên được hiểu là một dấu hiệu cho thấy bộ giải mã JSON có vấn đề với UTF-8.

Vì vậy, tôi đoán bạn chỉ có thể quyết định để sử dụng như thế này:

  • Chỉ cần sử dụng UTF-8, trừ khi phương pháp của bạn lưu trữ hoặc vận chuyển giữa bộ mã hóa và giải mã là không nhị phân-an toàn.

  • Nếu không, hãy sử dụng trình tự thoát số.

10

ASCII không còn ở trong đó nữa. Sử dụng mã hóa UTF-8 có nghĩa là bạn không sử dụng mã hóa ASCII. Những gì bạn nên sử dụng các cơ chế thoát cho là những gì các RFC nói:

nhân vật Tất cả Unicode có thể được đặt trong dấu ngoặc kép trừ cho các nhân vật đó phải thoát: dấu ngoặc kép, đảo ngược gạch chéo ở cuối, và các ký tự điều khiển (U + 0000 đến U + 001F)

+0

Nếu đọc báo giá bạn cung cấp, bạn sẽ thấy bạn không cần phải thoát khỏi tất cả các ký tự unicode, chỉ một vài ký tự đặc biệt. Nhưng bạn được yêu cầu mã hóa các kết quả (tốt nhất là với utf-8). Vì vậy, câu hỏi là: "Tại sao bận tâm thoát các ký tự unicode bình thường nếu bạn đang mã hóa utf-8". – schickb

+0

Ngoài ra, một chuỗi mã hóa ascii là một tập con tinh khiết của utf-8. Nếu tôi sử dụng thoát của json cho tất cả các ký tự không phải ascii, kết quả là ascii - và do đó utf-8. Các thư viện json khác nhau (như python simplejson) có các chế độ để ép buộc các kết quả ascii. Tôi đoán một lý do, giống như có thể thực hiện trong trình duyệt. – schickb

+0

Khi bạn bận tâm thoát khỏi các ký tự unicode bình thường là trong các ngữ cảnh mà chúng là siêu ký tự, như chuỗi. (RFC đoạn tôi trích dẫn là về dây, xin lỗi, không rõ ràng về điều đó.) Bạn không cần phải làm ASCII đầu ra tất cả các thời gian; Tôi nghĩ rằng đó là nhiều hơn cho gỡ lỗi với các trình duyệt bị hỏng. – chaos

14

Tôi gặp sự cố ở đó. Khi tôi mã hóa JSON một chuỗi có ký tự như "é", mọi trình duyệt sẽ trả về cùng "é", ngoại trừ IE sẽ trả về "\ u00e9".

Sau đó, với PHP json_decode(), nó sẽ thất bại nếu nó tìm thấy "é", vì vậy đối với Firefox, Opera, Safari và Chrome, tôi đã gọi utf8_encode() trước json_decode().

Lưu ý: với các thử nghiệm của tôi, IE và Firefox đang sử dụng đối tượng JSON gốc của họ, các trình duyệt khác đang sử dụng json2.js.

+10

Có lẽ bạn có nghĩa là 'utf8_encode()', http://php.net/manual/en/function.utf8-encode.php – Binyamin

+4

Nếu IE không giải mã được, đó là lỗi trong bất kỳ bộ giải mã JSON nào bạn đang sử dụng. Tất cả bộ giải mã JSON phải giải mã thành công biểu mẫu được mã hóa hoặc chúng không phải là bộ giải mã JSON. Đối với vấn đề của bạn với json_decode() với é unescaped, có thể là văn bản bạn đang cho ăn không phải là UTF-8. Bộ giải mã JSON luôn giả định UTF-8, ngay cả khi thực thi PHP, mặc dù PHP thường không giả định UTF-8 trong nhiều hàm khác. Có các bảng mã ký tự khác có thể bao gồm một ký tự không bị tắt và trông giống hệt nhau trên màn hình, nhưng không phải là UTF-8. Việc mã hóa trong biểu mẫu \ uXXXX là một giải pháp cho việc này. – thomasrutter

+0

Chỉ cần nói: JSON hợp pháp có thể có bất kỳ mã hóa Unicode nào (UTF-8, UTF-16 BE/LE, UTF32 BE/LE, có hoặc không có dấu thứ tự byte). Và vì ASCII là một tập hợp con của UTF-8, nó cũng có thể có trong ASCII. Cho dù các trình phân tích cú pháp chấp nhận UTF-32 chẳng hạn, tôi không biết. – gnasher729

0

Tôi đã có một vấn đề tương tự với é char ... Tôi nghĩ rằng nhận xét "có thể là văn bản bạn đang cho ăn nó không phải là UTF-8" có thể gần với nhãn hiệu ở đây. Tôi có cảm giác collation mặc định trong trường hợp của tôi là cái gì khác cho đến khi tôi nhận ra và thay đổi thành utf8 ... vấn đề là dữ liệu đã có, do đó, không chắc chắn nếu nó chuyển đổi dữ liệu hay không khi tôi thay đổi nó, hiển thị tốt trong mysql bàn làm việc. Kết quả cuối cùng là php sẽ không mã hóa dữ liệu, chỉ trả về false. Không có vấn đề gì trình duyệt bạn sử dụng như là máy chủ của nó gây ra vấn đề của tôi, php sẽ không phân tích dữ liệu để utf8 nếu char này là hiện tại. Giống như tôi nói không chắc chắn nếu nó là do chuyển đổi lược đồ để utf8 sau khi dữ liệu đã có mặt hoặc chỉ là một lỗi php. Trong trường hợp này, hãy sử dụng json_encode(utf8_encode($string));

3

Tôi đang gặp phải sự cố tương tự. Nó làm việc cho tôi. Làm ơn kiểm tra cái này.

json_encode($array,JSON_UNESCAPED_UNICODE); 
Các vấn đề liên quan