بررسی کلیدهای تکراری JSON
ابزار آموزشی رایگان این صفحه فقط در مرورگر اجرا میشود؛ داده به سرور ارسال نمیشود.
اگر متن JSON یک نام را در همان شیء دو بار تکرار کند، ممکن است تجزیهگر آن را بپذیرد و فقط آخرین مقدار را نگه دارد. در این حالت، ابزار بررسی JSON Schema که بعد از تجزیه اجرا میشود، دیگر الزاماً متن اولیه و مقدار حذفشده را نمیبیند. برای دادههایی که قرار است مبنای ثبت درخواست یا اجرای ابزار شوند، سیاست کلید تکراری را قبل از تبدیل نهایی به دیکشنری روشن کنید.
یک مثال کوتاه که خطا را پنهان میکند
{"quantity": 1, "quantity": 20}اگر گیرنده فقط quantity برابر ۲۰ را نگه دارد، این شیء از دید یک schema با شرط «عدد صحیح مثبت» میتواند پذیرفته شود. بررسی ساختارِ حاصل بهتنهایی نشان نمیدهد فرستنده همان نام را دو بار نوشته بود. هدف این راهنما حل خطای «عدد در برابر رشته» نیست؛ درباره اطلاعاتی است که هنگام تجزیه از بین میرود.
RFC 8259 یکتابودن نامها را برای سازگاری توصیه میکند و درباره رفتار متفاوت دریافتکنندهها توضیح میدهد. بنابراین نمیگوییم همه تجزیهگرها الزاماً باید یک خطای نحوی یکسان بدهند؛ برنامه شما باید قرارداد مشخص خود را انتخاب و آزمایش کند.
نمونه پایتون: هنگام خواندن جفتها تکرار را رد کنیم
در ماژول json پایتون میتوان با object_pairs_hook فهرست جفتهای نام و مقدار هر شیء را پیش از تبدیل پیشفرض بررسی کرد. نمونه زیر در هر شیء، نام تکراری را رد میکند. محدودیت اندازه ۶۴ هزار بایت، انتخاب همین مثال آموزشی است و تعرفه یا سقف API محصولی نیست.
import json
def unique_object(pairs):
result = {}
for key, value in pairs:
if key in result:
raise ValueError("Duplicate object key: " + key)
result[key] = value
return result
def reject_nonfinite(token):
raise ValueError("Non-finite number: " + token)
def read_checked_json(raw):
if len(raw.encode("utf-8")) > 64_000:
raise ValueError("Input too large for this example")
return json.loads(raw, object_pairs_hook=unique_object,
parse_constant=reject_nonfinite)
این تابع نامها را پس از رمزگشایی JSON مقایسه میکند. در نتیجه، نوشتن یک نام با escape هم نباید راهی برای پنهانکردن همان تکرار باشد. با وجود این، تابع بالا اختلاف معنایی دو نام متفاوت مانند quantity و qty را تشخیص نمیدهد؛ اینها از نظر رشته دو کلیدند و قواعد کسبوکار باید رفتارشان را تعریف کند.
سه آزمون ضروری برای همین کنترل
| ورودی آموزشی | انتظار قرارداد |
|---|---|
| {"quantity":1,"quantity":20} | رد: نام quantity در یک شیء تکرار شده |
| [{"id":1},{"id":2}] | پذیرش این کنترل: id در دو شیء جداست |
| {"role":"a","\u0072ole":"b"} | رد: هر دو نام پس از رمزگشایی role هستند |
اگر دو شیء مستقل هرکدام فیلد id دارند، آن را با نام تکراری در یک شیء اشتباه نگیرید. برای بررسی ساختار تو در تو نیز یک نمونه با تکرار در شیء داخلی بسازید. پیام خطای این کد نام فیلد را نشان میدهد، اما مسیر کامل آن را نمیسازد؛ اگر برنامه مسیر دقیق لازم دارد، باید این نیاز را جدا در انتخاب تجزیهگر بررسی کنید.
بعد از رد تکرار، اعتبارسنجی تمام نشده است
یکتایی نامها فقط یک کنترل در مرز دریافت است. سپس اعتبارسنجی خروجی مدل با JSON Schema باید نوع، فیلدهای لازم و محدودهها را بررسی کند. بعد از آن، شناسه مخاطب، مبلغ و مجوز انجام کار باید با منبع معتبر و هویت کاربر تطبیق داده شوند. هیچکدام را از متن پاسخ مدل معتبر فرض نکنید.
نمونه بالا چارچوب کامل پردازش داده نامطمئن نیست. عمق تو در تو، زمان پردازش، محدوده عدد و رفتار خطا هم باید در محیط مورد استفاده محدود و آزمایش شوند. برای آزمون، از متن ساختگی استفاده کنید و ابتدا فقط نتیجه تجزیه را ببینید؛ کد نمونه هیچ رکوردی ثبت نمیکند و ابزاری را اجرا نمیکند.
کدام خطا را کجا ثبت کنیم؟
در گزارش فنی، «متن دریافتشده دارای نام تکراری بود» را از «شیء با schema ناسازگار بود» جدا ثبت کنید. اگر متن اولیه حاوی داده حساس است، برای گزارش عمومی کل آن را کپی نکنید؛ نام کنترل و یک شناسه ردیابی کافی میتواند باشد. برای طراحی نمایش خروجی نیز راهنمای نمایش امن متن تولیدشده را بخوانید.
اگر این خروجی قرار است در فرایند پاسخگویی به مشتری استفاده شود، نمونه قرارداد داده و چند ورودی مرزی را برای بررسی مسیر راهاندازی همراه بیاورید. وجود این راهنما، به معنی فعالبودن API یا انجام خودکار عملیات خاصی در محصولات اپرا نیست.
منابع و تاریخ بررسی
این منابع در ۳ نوامبر ۲۰۲۶ بررسی شدهاند. عددهای مثالها آموزشی و ساخته تحریریهاند؛ نتیجه آزمون یک محصول یا مشتری نیستند.
ادامه مسیر یادگیری
شمارش کاراکتر فارسی؛ تفاوت نویسه، بایت و طول رشته — برای کنترل سقف حجم ورودی، شمارنده فارسی بایت UTF-8 را از تعداد نویسهها جدا نشان میدهد.