مقدمه
ثبت خطای شبکه (NEL) مکانیزمی برای جمع آوری خطاهای شبکه سمت سرویس گیرنده از مبدا است.
از هدر پاسخ NEL
HTTP استفاده میکند تا به مرورگر بگوید خطاهای شبکه را جمعآوری کند، سپس با Reporting API ادغام میشود تا خطاها را به سرور گزارش کند.
مروری بر API گزارش قدیمی
میراث Report-To
سربرگ
برای استفاده از گزارش API قدیمی، باید سرصفحه پاسخ Report-To
HTTP را تنظیم کنید. مقدار آن یک شی است که یک گروه نقطه پایانی را برای مرورگر توصیف می کند تا خطاها را به آن گزارش کند:
Report-To:
{
"max_age": 10886400,
"endpoints": [{
"url": "https://analytics.provider.com/browser-errors"
}]
}
اگر نشانی وب نقطه پایانی شما در مبدأ متفاوتی از سایت شما قرار دارد، نقطه پایانی باید از درخواستهای پیش از پرواز CORS پشتیبانی کند. (به عنوان مثال Access-Control-Allow-Origin: *; Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS; Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With
).
در مثال، ارسال این سرصفحه پاسخ همراه با صفحه اصلی، مرورگر را پیکربندی میکند تا هشدارهای ایجاد شده توسط مرورگر را به نقطه پایانی https://analytics.provider.com/browser-errors
برای max_age
ثانیه گزارش کند. توجه به این نکته مهم است که تمام درخواست های HTTP بعدی که توسط صفحه (برای تصاویر، اسکریپت ها و غیره) انجام می شود نادیده گرفته می شوند. پیکربندی در هنگام پاسخ به صفحه اصلی تنظیم می شود.
توضیح فیلدهای هدر
هر پیکربندی نقطه پایانی شامل نام group
، max_age
و آرایه endpoints
است. همچنین میتوانید با استفاده از فیلد include_subdomains
انتخاب کنید که آیا هنگام گزارش خطا، زیر دامنهها را در نظر بگیرید یا خیر.
میدان | تایپ کنید | توضیحات |
---|---|---|
group | رشته | اختیاری. اگر نام group مشخص نشده باشد، به نقطه پایانی یک نام "پیش فرض" داده می شود. |
max_age | شماره | مورد نیاز . یک عدد صحیح غیر منفی که طول عمر نقطه پایانی را بر حسب ثانیه تعریف می کند. مقدار "0" باعث می شود گروه نقطه پایانی از حافظه پنهان گزارش عامل کاربر حذف شود. |
endpoints | آرایه<Object> | مورد نیاز . آرایه ای از اشیاء JSON که نشانی وب واقعی جمع آوری کننده گزارش شما را مشخص می کند. |
include_subdomains | بولی | اختیاری. یک بولین که گروه نقطه پایانی را برای همه زیر دامنههای میزبان مبدا فعلی فعال میکند. در صورت حذف یا هر چیزی غیر از "درست"، زیر دامنه ها به نقطه پایانی گزارش نمی شوند. |
نام group
یک نام منحصر به فرد است که برای مرتبط کردن یک رشته با یک نقطه پایانی استفاده می شود. از این نام در مکانهای دیگری که با Reporting API ادغام میشوند برای اشاره به یک گروه نقطه پایانی خاص استفاده کنید.
قسمت max-age
نیز لازم است و مشخص میکند که مرورگر چه مدت باید از نقطه پایانی استفاده کند و خطاها را به آن گزارش کند.
فیلد endpoints
آرایه ای برای ارائه ویژگی های Failover و متعادل کننده بار است. به بخش Failover و تعادل بار مراجعه کنید. توجه به این نکته مهم است که مرورگر فقط یک نقطه پایانی را انتخاب می کند ، حتی اگر گروه چندین جمع کننده را در endpoints
لیست کند. اگر می خواهید گزارشی را همزمان به چندین سرور ارسال کنید، باطن شما باید گزارش ها را فوروارد کند.
مرورگر چگونه گزارش ها را ارسال می کند؟
مرورگر به صورت دورهای گزارشها را دستهبندی میکند و آنها را به نقاط پایانی گزارشی که پیکربندی میکنید ارسال میکند.
برای ارسال گزارشها، مرورگر یک درخواست POST
با Content-Type: application/reports+json
و بدنهای حاوی آرایهای از هشدارها/خطاهای ثبت شده صادر میکند.
مرورگر چه زمانی گزارش ها را ارسال می کند؟
گزارشها خارج از باند از برنامه شما تحویل داده میشوند ، به این معنی که مرورگر زمان ارسال گزارشها به سرور(های) شما را کنترل میکند.
مرورگر سعی می کند گزارش های صف را در مناسب ترین زمان ارائه دهد. این ممکن است به محض آماده شدن (به منظور ارائه بازخورد به موقع به توسعهدهنده) انجام شود، اما مرورگر همچنین میتواند تحویل را به تعویق بیندازد اگر مشغول پردازش کارهای با اولویت بالاتر باشد، یا اگر کاربر در یک شبکه کند و/یا شلوغ است. زمان اگر کاربر بازدیدکننده مکرر باشد، ممکن است مرورگر ابتدا ارسال گزارشهای مربوط به یک منبع خاص را در اولویت قرار دهد.
هنگام استفاده از Reporting API هیچ نگرانی عملکردی وجود ندارد (مثلاً اختلاف شبکه با برنامه شما). همچنین هیچ راهی برای کنترل زمانی که مرورگر گزارش های در صف ارسال می کند وجود ندارد.
پیکربندی چندین نقطه پایانی
یک پاسخ می تواند چندین نقطه پایانی را همزمان با ارسال چندین هدر Report-To
پیکربندی کند:
Report-To: {
"group": "default",
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/browser-reports"
}]
}
Report-To: {
"group": "network-errors-endpoint",
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/network-errors"
}]
}
یا با ترکیب آنها در یک هدر HTTP:
Report-To: {
"group": "network-errors-endpoint",
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/network-errors"
}]
},
{
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/browser-errors"
}]
}
هنگامی که هدر Report-To
را ارسال کردید، مرورگر نقاط پایانی را با توجه به مقادیر max_age
در حافظه پنهان ذخیره میکند و همه آن هشدارها/خطاهای ناخوشایند کنسول را به آدرسهای اینترنتی شما ارسال میکند.
Failover و Load Balanceing
بیشتر اوقات شما در هر گروه یک جمعآورنده URL را پیکربندی میکنید. با این حال، از آنجایی که گزارش میتواند حجم خوبی از ترافیک ایجاد کند، این مشخصات شامل ویژگیهای Failover و Load-balancing است که از رکورد DNS SRV الهام گرفته شده است.
مرورگر تمام تلاش خود را برای ارائه گزارش حداکثر به یک نقطه پایانی در یک گروه انجام می دهد. به نقاط پایانی می توان weight
برای توزیع بار اختصاص داد که هر نقطه پایانی بخش مشخصی از ترافیک گزارش را دریافت می کند. همچنین میتوان برای راهاندازی جمعآوریکنندههای بازگشتی، به نقاط پایانی priority
اختصاص داد.
جمعآوران بازگشتی فقط زمانی امتحان میشوند که بارگذاریها در مجموعههای اصلی با شکست مواجه شوند.
مثال : در https://backup.com/reports
یک گردآورنده بازگشتی ایجاد کنید:
Report-To: {
"group": "endpoint-1",
"max_age": 10886400,
"endpoints": [
{"url": "https://example.com/reports", "priority": 1},
{"url": "https://backup.com/reports", "priority": 2}
]
}
راه اندازی ثبت خطاهای شبکه
راه اندازی
برای استفاده از NEL، هدر Report-To
را با مجموعهای تنظیم کنید که از یک گروه نامگذاری شده استفاده میکند:
Report-To: {
...
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://analytics.provider.com/networkerrors"
}]
}
در مرحله بعد، هدر پاسخ NEL
را برای شروع جمع آوری خطاها ارسال کنید. از آنجایی که NEL برای یک مبدا انتخاب شده است، شما فقط باید یک بار هدر را ارسال کنید. هر دو NEL
و Report-To
برای درخواستهای آینده با مبدأ یکسان اعمال میشوند و به جمعآوری خطاها بر اساس مقدار max_age
که برای راهاندازی جمعآور استفاده شده است، ادامه میدهند.
مقدار هدر باید یک شی JSON باشد که حاوی یک قسمت max_age
و report_to
باشد. از دومی برای ارجاع به نام گروه جمع آوری کننده خطاهای شبکه خود استفاده کنید:
GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}
منابع فرعی
مثال : اگر example.com
foobar.com/cat.gif
را بارگیری کند و آن منبع بارگیری نشود:
- به جمع آوری کننده NEL
foobar.com
اطلاع داده شده است - به جمع آوری کننده NEL
example.com
اطلاع داده نمی شود
قانون سرانگشتی این است که NEL گزارشهای سمت سرور را که فقط روی کلاینت ایجاد شدهاند، بازتولید میکند.
از آنجایی که example.com
هیچ دیدی در گزارشهای سرور foobar.com
ندارد، در گزارشهای NEL خود نیز دیده نمیشود.
اشکال زدایی تنظیمات گزارش
اگر گزارشهایی را که روی سرورتان نمایش داده نمیشوند، به chrome://net-export/
مراجعه کنید. آن صفحه برای تأیید پیکربندی صحیح موارد و ارسال صحیح گزارش ها مفید است.
در مورد ReportingObserver چطور؟
ReportingObserver
یک مکانیسم گزارش دهی مرتبط اما متفاوت است. این بر اساس فراخوانی جاوا اسکریپت است. برای ثبت خطاهای شبکه مناسب نیست ، زیرا خطاهای شبکه را نمی توان از طریق جاوا اسکریپت رهگیری کرد.
سرور نمونه
در زیر نمونه ای از سرور Node است که از Express استفاده می کند. نحوه پیکربندی گزارش برای خطاهای شبکه را نشان می دهد و یک کنترل کننده اختصاصی برای ثبت نتیجه ایجاد می کند.
const express = require('express');
const app = express();
app.use(
express.json({
type: ['application/json', 'application/reports+json'],
}),
);
app.use(express.urlencoded());
app.get('/', (request, response) => {
// Note: report_to and not report-to for NEL.
response.set('NEL', `{"report_to": "network-errors", "max_age": 2592000}`);
// The Report-To header tells the browser where to send network errors.
// The default group (first example below) captures interventions and
// deprecation reports. Other groups, like the network-error group, are referenced by their "group" name.
response.set(
'Report-To',
`{
"max_age": 2592000,
"endpoints": [{
"url": "https://reporting-observer-api-demo.glitch.me/reports"
}],
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://reporting-observer-api-demo.glitch.me/network-reports"
}]
}`,
);
response.sendFile('./index.html');
});
function echoReports(request, response) {
// Record report in server logs or otherwise process results.
for (const report of request.body) {
console.log(report.body);
}
response.send(request.body);
}
app.post('/network-reports', (request, response) => {
console.log(`${request.body.length} Network error reports:`);
echoReports(request, response);
});
const listener = app.listen(process.env.PORT, () => {
console.log(`Your app is listening on port ${listener.address().port}`);
});