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.
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?
- Tương thích phổ quát · JSON được hỗ trợ bởi hầu như tất cả ngôn ngữ lập trình và công cụ.
- Quản lý cấu hình · Nhiều công cụ mong đợi JSON cho việc cấu hình hoặc trao đổi dữ liệu.
- Tích hợp API · API web thường yêu cầu định dạng JSON.
- Xử lý dữ liệu · Chuyển đổi tệp cấu hình YAML để sử dụng trong các quy trình tự động.
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ả
- Bản thảo 0.1: 11 tháng 5 năm 2001, thông báo trên mailing list sml-dev.
- YAML 1.0: 29 tháng 1 năm 2004, đặc tả ổn định đầu tiên, bởi Ben-Kiki, Evans và Ingy döt Net.
- YAML 1.1: 18 tháng 1 năm 2005, phiên bản mà hầu hết các parser «legacy» vẫn mô phỏng theo mặc định. Nguồn gốc của Norway Problem và hầu hết các quirk kiểu ngầm định.
- YAML 1.2.0: 21 tháng 7 năm 2009, bản sửa đổi đầu tiên với mục tiêu «JSON superset» rõ ràng. Kiểu ngầm định được viết lại để căn chỉnh với các token của JSON.
- YAML 1.2.1: 1 tháng 10 năm 2009, bản làm mới chỉ sửa errata của 1.2.0.
- YAML 1.2.2: 1 tháng 10 năm 2021, bản sửa đổi corrigenda bởi Nhóm Phát triển Ngôn ngữ YAML mới thành lập năm 2020.
Đặ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 và .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, FALSE và khô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: |- và >- loại bỏ tất cả dòng mới đứng cuối, |+ và >+ 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
- Các biểu diễn null gộp lại. YAML chấp nhận
null,Null,NULL,~, và một giá trị trống (key:không có gì theo sau) là null. Cả năm đều trở thànhnullJSON, không thể phân biệt. - Comment biến mất lặng lẽ. Comment YAML bắt đầu bằng
#và đặc tả 1.2 nêu rõ chúng chỉ là phần trình bày, không phải một phần của mô hình dữ liệu. JSON không có cú pháp comment. Nếu bạn cần bảo toàn chúng, hãy lưu dưới dạng dữ liệu (ví dụ, trường_comment) trước khi chuyển đổi. - Key phi-string bị ép buộc. Ánh xạ YAML cho phép bất kỳ node nào làm key, bao gồm số nguyên (
1: foo), boolean (true: yes), và thậm chí các chuỗi lồng nhau. JSON yêu cầu key chuỗi. Hầu hết converter chuyển thành chuỗi ("1": "foo"); một số thì báo lỗi. - Tag thường bị bỏ. Các tag tùy chỉnh như
!!set,!!omap, hoặc!myapp/Typedành riêng cho ứng dụng không có tương đương JSON. - Datetime round-trip dưới dạng chuỗi. Ngày hoặc timestamp YAML thường trở thành chuỗi ISO 8601 trong JSON, vì JSON không có kiểu ngày gốc.
- Số nguyên lớn mất độ chính xác trong JavaScript. Số JSON là các double IEEE 754 trong JS, vì vậy một số nguyên YAML như
9007199254740993lặng lẽ trở thành9007199254740992sau khi chuyển đổi. - Anchor được mở rộng. Một graph YAML chia sẻ cây con qua nhiều vị trí trở thành cây JSON với cây con đó được nhân đôi. Tham chiếu vòng (mà YAML cho phép) hoàn toàn không thể biểu diễn trong JSON.
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).