Trình chuyển đổi YAML sang JSON miễn phí

Chuyển đổi YAML sang JSON ngay lập tức. Xử lý tất cả cú pháp YAML bao gồm danh sách, bản đồ và anchor. Chạy hoàn toàn trong trình duyệt của bạn.

Dữ liệu của bạn không bao giờ rời khỏi thiết bị
Thả tệp YAML vào đây hoặc nhấp để duyệt (tối đa 5 MB)

YAML là gì?

YAML (YAML Ain't Markup Language) là một định dạng tuần tự hóa dữ liệu thân thiện với con người thường được sử dụng cho các tệp cấu hình. Nó sử dụng kiểu thụt lề và cú pháp đơn giản để biểu diễn các cấu trúc dữ liệu như danh sách, từ điển và giá trị vô hướng.

Tại sao chuyển đổi YAML sang JSON?

Câu hỏi thường gặp

Những tính năng YAML nào được hỗ trợ?

Trình chuyển đổi hỗ trợ tất cả các tính năng YAML tiêu chuẩn bao gồm bản đồ, danh sách, chuỗi, số, boolean, null, chuỗi nhiều dòng, anchor và alias.

Cấu trúc YAML phức tạp của tôi có được chuyển đổi đúng không?

Có. Trình chuyển đổi xử lý các cấu trúc lồng nhau, danh sách đối tượng, bình luận (sẽ bị loại bỏ) và tất cả cú pháp YAML. Nếu có lỗi cú pháp, bạn sẽ nhận được thông báo lỗi rõ ràng.

Bình luận YAML có được giữ lại không?

Không. Bình luận không phải là một phần của cấu trúc dữ liệu, nên chúng không được bao gồm trong đầu ra JSON.

Lịch sử ngắn về YAML, một dự án phân nhánh từ mailing list năm 2001

Tiền sử của YAML bắt đầu trên mailing list sml-dev, một nhánh những năm 2000 của xml-dev, nơi tập hợp những người cho rằng XML quá phức tạp cho dữ liệu do con người chỉnh sửa. Hai hướng song song hội tụ: module Perl Data::Denter của Ingy döt Net, được viết như định dạng serialize cho module Inline Perl, và công việc chung của Oren Ben-Kiki và Clark Evans nhằm đơn giản hóa XML. Vào ngày 11 tháng 5 năm 2001, Clark Evans đã đăng «YAML Draft 0.1» lên sml-dev, và định dạng này được công bố lần đầu trong một bài viết xmlhack vào ngày hôm sau.

Cách mở rộng ban đầu của từ viết tắt mang tính tự trào: Yet Another Markup Language, một sự châm biếm về sự phổ biến ồ ạt của các định dạng markup năm 2001. Từ tháng 12 năm 2001 đến tháng 4 năm 2002, các tác giả đã tái thiết kế backronym đệ quy YAML Ain't Markup Language: một phần để nhấn mạnh rằng YAML là định dạng serialize dữ liệu chứ không phải định dạng đánh dấu tài liệu như XML hay HTML, và một phần vì trò đùa đã hết thời. Cách mở rộng đệ quy vẫn là khẩu hiệu chính thức trên yaml.org ngày nay.

Dòng thời gian đặc tả

Đặc tả 1.2.2 nêu rõ rằng «không có thay đổi chuẩn nào so với đặc tả YAML v1.2»; công việc bao gồm việc chuyển đổi nguồn từ DocBook sang Markdown, tái tạo sơ đồ từ LaTeX văn bản thuần túy, và mở quy trình phát triển để các đóng góp viên bên ngoài có thể gửi pull request đối chiếu với đặc tả. Không có ngôn ngữ nào được phát hành kể từ năm 2009: mọi lỗi tuân thủ parser kể từ đó hoặc là lỗi tồn đọng từ 1.1 hoặc là sai lệch so với một đặc tả hiện đã đứng vững hơn mười lăm năm. Kiểu MIME chính thức application/yaml được hoàn thiện năm 2024; các phần mở rộng file .yaml.yml đều được công nhận từ khoảng năm 2006, với .yaml là phần mở rộng được khuyến nghị.

Quan hệ với JSON, «gần như superset»

Đặc tả YAML 1.2.2 viết thận trọng: «Hoàn toàn tình cờ, JSON gần như là một subset hoàn chỉnh của YAML.» JSON xuất hiện giữa YAML 1.0 (2004) và YAML 1.1 (2005); các tác giả YAML chỉ phát hiện ra sự trùng lặp sau đó. Mục tiêu rõ ràng của bản sửa đổi 1.2, theo chính lời của nó, là «biến YAML thành superset nghiêm ngặt của JSON», và điều này gần như đúng với các tài liệu YAML 1.2 được định dạng JSON nhưng không đúng với YAML 1.1.

Về mặt thực tế: mọi tài liệu JSON đều là YAML 1.2 hợp lệ, ánh xạ kiểu flow {"a": 1, "b": [true, null]} được parse giống hệt nhau trong cả hai. Hầu hết tài liệu JSON không phải YAML 1.1 hợp lệ vì các gotcha boolean và Norway: một tài liệu JSON chứa chuỗi ký tự "NO" sẽ được phát lại là false nếu round-trip qua một parser 1.1 sử dụng cài đặt mặc định. Điều ngược lại không bao giờ đúng: YAML có thể biểu diễn những thứ JSON không thể, comment (mất khi chuyển đổi), anchor và alias (được giải quyết khi chuyển đổi), tag (thường bị loại bỏ), luồng multi-document (chỉ tài liệu đầu tiên hoặc tất cả-thành-mảng tồn tại), và các key phi-string trên ánh xạ.

Norway Problem

Gotcha được trích dẫn nhiều nhất của YAML. Được đặt tên theo Na Uy vì mã quốc gia hai chữ cái ISO 3166-1 của Na Uy là NO, và regex boolean của YAML 1.1 khớp NO là boolean false. Viết country: NO trong YAML 1.1 (hoặc trong bất kỳ parser 1.2 nào vẫn mặc định theo hành vi 1.1, tức là hầu hết), parse nó, dump ra JSON, và bạn nhận được {"country": false}. Lỗi im lặng, không có cảnh báo, không có lỗi kiểu, chỉ là hỏng dữ liệu.

Regex boolean YAML 1.1 đầy đủ từ schema chính thức yaml.org/type/bool.html là:

y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF

Đó là sáu lexeme (y/n, yes/no, on/off, true/false) với ba biến thể chữ hoa mỗi loại, hai mươi hai chuỗi tất cả đều trở thành boolean mà không cảnh báo. Một danh sách phản hồi hợp lệ [y, n, maybe] trở thành [true, false, "maybe"]; cờ tính năng dark_mode: on được parse là dark_mode: true; cài đặt port-mode viết OFF trở thành false. YAML 1.2 đã sửa điều này ở cấp đặc tả: schema lõi căn chỉnh JSON chỉ nhận ra true, True, TRUE, false, False, FALSEkhông nhận ra y/n/yes/no/on/off chút nào. Nhưng bản sửa này chưa lan rộng ra thực tế, PyYAML và LibYAML vẫn là 1.1-mặc định trong tất cả các phiên bản hiện đang được phát hành. Converter này sử dụng js-yaml v4, mặc định là schema YAML 1.2 / tương thích JSON; đây là một lý do tại sao converter phía trình duyệt thực ra an toàn hơn khi chạy yaml.load() trong PyYAML rồi chuyển đổi từ đó.

Các bẫy kiểu ngầm định khác

Số octal. YAML 1.1 theo quy ước C: số 0 đứng đầu có nghĩa là octal. Vì vậy 010 được parse là số nguyên 8, và permissions: 0777 (một cách viết tự nhiên cho chế độ file Unix) được parse là 511. Bản sửa YAML 1.2 là yêu cầu tiền tố 0o rõ ràng theo Python hiện đại, 0o777 là 511, và 0777 chỉ là 777. Các parser mắc kẹt ở mặc định 1.1 vẫn còn hiểu sai điều này.

Số sexagesimal. YAML 1.1 kế thừa từ các định dạng serialize trước đó quy ước rằng bất kỳ chuỗi các nhóm chữ số thập phân nào được phân tách bằng dấu hai chấm đều được parse là số nguyên hoặc số thực cơ số 60 (sexagesimal). Use case được quảng bá là thời gian: 1:11:00 sẽ được parse là số nguyên 4260 (một giờ, mười một phút tính bằng giây). Quy tắc này vẫn gây phiền não trong thực tế khi mọi người viết timestamp như 21:00 hoặc số phiên bản như 2:3:4 rồi thấy chúng lặng lẽ bị ép buộc thành số nguyên. Sexagesimal đã được xóa lặng lẽ trong YAML 1.2, nhưng PyYAML và các parser 1.1-mặc định khác vẫn áp dụng.

Tự động chuyển đổi datetime. YAML 1.1 cũng tự phát hiện timestamp ISO 8601 và parse chúng thành kiểu ngày/giờ gốc của ngôn ngữ host, đây là vấn đề nếu bạn muốn một chuỗi. Viết version: 2024-01-15 và bạn nhận được một đối tượng date Python, không phải chuỗi "2024-01-15". Bài học chung, được nhấn mạnh trong bài luận «YAML document from hell» của Ruud van Asseldonk: luôn đặt trong nháy những chuỗi có thể được parse là thứ gì khác. Mã quốc gia, số phiên bản, chế độ file, timestamp, và bất kỳ giá trị nào được rút từ vốn từ vựng cố định nên được bọc trong nháy đơn hoặc nháy đôi.

Anchor, alias và merge key

Hệ thống anchor/alias của YAML cho phép bạn gắn nhãn một node với &name và tái sử dụng nó sau bằng *name. Ví dụ điển hình:

defaults: &defaults
  timeout: 30
  retries: 3
production:
  <<: *defaults
  host: prod.example.com

Ở đây &defaults neo ánh xạ, và <<: *defaults (merge key (một tính năng schema 1.1 được hầu hết parser giữ lại) ghép nó vào khối production. Khi được chuyển đổi sang JSON, alias được giải quyết hoàn toàn) đầu ra JSON chứa nội dung lặp lại theo nghĩa đen, không phải tham chiếu. Anchor và alias biến mất, và mọi merge key đều được làm phẳng.

Chế độ lỗi nổi tiếng của hệ thống này là cuộc tấn công billion laughs: vì anchor có thể được alias nhiều lần và các target alias có thể tự chứa alias, một file YAML nhỏ có thể mở rộng thành một cấu trúc trong bộ nhớ khổng lồ (10 cấp × 10 lần lồng nhau = 10¹⁰ phần tử chuỗi). PyYAML, LibYAML và các công cụ khác phải thêm giới hạn mở rộng để giảm thiểu điều này. Các converter phía trình duyệt có giới hạn bộ nhớ tự nhiên (tab sẽ OOM trước khi host bị ảnh hưởng), nhưng rủi ro cấu trúc là có thật.

Luồng multi-document và front matter

Một luồng YAML có thể chứa nhiều hơn một tài liệu. Các tài liệu được phân tách bằng một dòng chứa chính xác --- (cũng được dùng như marker kết thúc chỉ thị ở đầu tài liệu đầu tiên, đó là lý do tại sao front matter trong Jekyll, Hugo và Eleventy được bao quanh bởi các dòng ---). Một dòng chứa ... đánh dấu kết thúc một tài liệu mà không bắt đầu tài liệu mới, hữu ích trong các giao thức streaming.

Kubernetes sử dụng --- để gói nhiều resource manifest trong một file. JSON không có tương đương. Một converter có ba lựa chọn khi gặp YAML multi-document: chỉ phát ra tài liệu đầu tiên, phát ra một mảng JSON các tài liệu, hoặc phát ra một tài liệu JSON mỗi lần phân tách --- được ngăn cách bởi dòng mới (JSON Lines). Hầu hết converter mặc định theo tùy chọn đầu tiên hoặc thứ hai; loadAll của js-yaml trả về một mảng.

Chuỗi nhiều dòng, folded so với literal

YAML có hai kiểu block-scalar. Kiểu literal (|) bảo toàn dòng mới chính xác. Kiểu folded (>) thay thế dấu xuống dòng đơn bằng dấu cách và bảo toàn dòng trống như dấu phân cách đoạn. Cả hai đều chấp nhận chỉ báo chomping: |->- loại bỏ tất cả dòng mới đứng cuối, |+>+ giữ lại tất cả, và | hoặc > không được sửa đổi («clip») bảo toàn một dòng mới đứng cuối duy nhất. Khi được chuyển đổi sang JSON, cả hai kiểu đều tạo ra các giá trị chuỗi thông thường, khối folded trở thành một chuỗi dài với \n nhúng chỉ ở các dòng trống được bảo toàn; khối literal có \n ở mọi dấu xuống dòng.

Những gì mất khi chuyển đổi

YAML thực sự được dùng ở đâu

YAML có mặt khắp nơi trong cơ sở hạ tầng hiện đại: Kubernetes manifests (toàn bộ mô hình đối tượng là YAML theo quy ước; các file multi-document phân tách bằng --- là chuẩn), Docker Compose (docker-compose.yml cho services, networks, volumes), GitHub Actions (.github/workflows/*.yml: schema YAML 1.2 nghiêm ngặt được tuân thủ hầu hết nhưng parser vẫn nhận ra on: là key, một near-miss của Norway Problem mà GitHub xử lý rõ ràng), GitLab CI/CD, Ansible playbooks, CircleCI / Travis CI / Drone / Bitbucket Pipelines, front matter của Jekyll / Hugo / Eleventy / Gatsby / Astro, đặc tả OpenAPI / Swagger (chính thức là «một JSON object có thể được biểu diễn dưới dạng JSON hoặc YAML»), cấu hình monitoring stack Prometheus / Grafana / Loki / Tempo, cloud-init (cung cấp lần khởi động đầu tiên cho VM EC2/GCE/Azure), và AWS CloudFormation / Azure Resource Manager / Google Cloud Deployment Manager. Với hầu hết các trường hợp này, chuyển đổi YAML-sang-JSON là thiết yếu khi bạn nhúng cấu hình vào các giao thức chỉ dùng JSON, so sánh file bằng jq, hoặc đưa đầu ra vào công cụ cần JSON.

Tại sao chuyển đổi phía trình duyệt an toàn hơn phía server

Hàm yaml.load() của PyYAML với cài đặt mặc định có thể thực thi mã Python tùy ý trên bất kỳ đầu vào không tin cậy nào thông qua tag !!python/object, tag này deserialize thành các đối tượng Python thực với tác dụng phụ, CVE-2017-18342, điểm CVSS v3.1 9,8 (Nghiêm trọng), được sửa trong PyYAML 5.1 (tháng 3 năm 2019) bằng cách loại bỏ mặc định không an toàn và làm cho safe_load() trở thành điểm vào được khuyến nghị. SnakeYAML của Java có tương đương riêng của nó (CVE-2022-1471, cũng điểm CVSS 9,8) liên quan đến lớp Constructor cho phép khởi tạo tùy ý. Crate serde_yaml de-facto của Rust bị deprecated vào tháng 3 năm 2024; hệ sinh thái vẫn đang ổn định trên người kế nhiệm (serde_yml, serde_yaml_ng, serde_norway).

Chạy phân tích cú pháp trong trình duyệt thông qua js-yaml v4 tránh được tất cả những điều này: không có server để xâm nhập, js-yaml không có khái niệm thực thi mã tùy ý qua tag (tag không xác định trở thành scalar thuần túy thay vì đối tượng được khởi tạo), và v4 mặc định theo schema 1.2 an toàn hơn. Công cụ Absolutool được hưởng lợi từ điều này theo mặc định.

Câu hỏi thêm

Converter xử lý file YAML multi-document như thế nào?

Nó tải chúng bằng loadAll của js-yaml, hàm trả về một mảng các tài liệu đã parse, đầu ra JSON do đó là một mảng JSON với một phần tử cho mỗi tài liệu được phân tách bằng ---. Nếu bạn chỉ có một tài liệu, bạn sẽ nhận được một mảng JSON với một phần tử; bọc đầu vào trong các marker ---/... nếu bạn muốn ngữ nghĩa tài liệu đơn rõ ràng.

Kubernetes manifest của tôi có chuyển đổi đúng không?

Hầu như luôn luôn là có. Kubernetes sử dụng nội dung tương thích YAML 1.2 hầu hết, và js-yaml v4 xử lý tất cả các kiểu nguyên thủy chuẩn (chuỗi, số nguyên, boolean, null, chuỗi tuần tự, ánh xạ) cộng với anchor và alias. Hai phần không tồn tại được là comment (bị loại bỏ) và bất kỳ anchor nào được mở rộng thành nội dung lặp lại thay vì tham chiếu.

Tại sao mã quốc gia NO của tôi lại được đọc như boolean?

Không nên xảy ra trong converter này, js-yaml v4 mặc định theo schema YAML 1.2 / tương thích JSON, không nhận ra y/n/yes/no/on/off là boolean. Nếu bạn gặp điều này trong công cụ khác (PyYAML chẳng hạn), cách sửa là bọc giá trị trong nháy: country: "NO".

Giới hạn kích thước file là bao nhiêu?

5 MB trên widget tải lên, nhưng nội dung dán có thể lớn hơn nếu trình duyệt của bạn có đủ bộ nhớ. Nút thắt là biểu diễn trong bộ nhớ, không phải mạng, không có server trong vòng lặp. Với các file lớn hơn khoảng 50 MB, hãy cân nhắc toolchain YAML trên máy tính để bàn (yq trên dòng lệnh chẳng hạn).

Công cụ liên quan