ブラウザのネットワークエラーをレポートさせるNetwork Error Loggingが来た

20180727追記
CORS対応が必要になりました
asnokaze.hatenablog.com

20180703追記
ドキュメントはhttps://w3c.github.io/network-error-logging/ にが移されました

20180608追記
仕様上は、jsonの各値はハイフンではなく、アンダースコアを使用するようになります

  • report-to => report_to
  • max-age => max_age
  • ... etc

https://github.com/WICG/network-error-logging/commit/86c4d1c0fa4c5d5ca1d8bdcd9fa931e7e4ab65c2

こんな感じ

nel: {"report_to": "network-errors", "max_age": 2592000, "include_subdomains": true, "success_fraction": 1}
report-to: { "endpoints": [{"url" : "https://asnokaze.com/report", "priority": 1}], "group": "network-errors", "max_age": 10886400, "include-subdomains":true}


以下本編


TCPコネクションタイムアウトTLS証明書エラー・名前解決エラー・リダイレクトループなど、ブラウザでは様々なネットワークエラーが発生します。ユーザ側の環境にも依存するため、サーバ側からは検知できない場合もあります。

そういったブラウザで発生したネットワークエラーをレポートさせる「Network Error Logging」がついに、Chrome開発版(dev) で利用できるようになったので試してみる

たまにdisableになってたりするけど、再起動すると使えたりする。。。

Network Error Logging

Network Error Logging」は、W3CのWICGで議論されている仕様です。

HTTPレスポンスヘッダで、nelヘッダを指定することでネットワークエラーを指定したエンドポイントに対してレポートするようになります。レポート先エンドポイントは「Reporting API」で定義されるように、report-toヘッダで別途指定します。

指定例

nel: {"report-to": "network-errors", "max-age": 3600, "include-subdomains": true,"success-fraction": 0}
report-to: { "endpoints": [{"url" : "https://asnokaze.com/report"}], "group": "network-errors","max-age": 10886400, "include-subdomains":true}

nelヘッダでは以下のような指定ができます

  • report-to: エンドポイントのグループ識別子(別途report-toヘッダで指定する)
  • max-age: このヘッダで指定される指示の有効期限
  • error-fraction: エラー発生時にレポートを送信する割合。1.0~0.0の間で指定
  • success-fraction: エラーが発生していなくてもレポートを送信する割合。1.0~0.0の間で指定
  • include-subdomains: サブドメインのネットワークエラーもレポートするか

このように指定すると、以後そのドメインでネットワークエラーが発生した場合に以下のようにレポートがPOSTされる。
404エラーが発生した場合と、名前解決エラーが発生した場合のレポート例です(jsonは整形済み)

どのページで、どういたネットワークエラーが発生したか確認できる。

[
	{
		"age": 240003,
		"report": {
			"elapsed-time": 33,
			"protocol": "http/1.1",
			"referrer": "https://asnokaze.com/nel.html",
			"sampling-fraction": 1,
			"server-ip": "160.16.124.39",
			"status-code": 404,
			"type": "http.error",
			"uri": "https://asnokaze.com/img/b.gif"
		},
		"type": "network-error",
		"url": "https://asnokaze.com/img/b.gif"
	},
	{
		"age": 147358,
		"report": {
			"elapsed-time": 7,
			"protocol": "",
			"referrer": "https://asnokaze.com/nel.html",
			"sampling-fraction": 1,
			"server-ip": "",
			"status-code": 0,
			"type": "dns.name_not_resolved",
			"uri": "https://nothing.asnokaze.com/"
		},
		"type": "network-error",
		"url": "https://nothing.asnokaze.com/"
	}
]

動作確認

Chromeの「chrome://net-internals/#reporting」より、Network Error Loggingが有効であること、レポートとして送信されるデータが確認できる
f:id:ASnoKaze:20180528205145p:plain

一応、NEL確認用ページ
https://asnokaze.com/nel.html

エラーの種類

Network Error Loggingでは様々なエラーが定義されています。

  • ok エラーはない
  • dns.unreachable DNSサーバへ到達できない
  • dns.name_not_resolved DNSサーバは応答したが名前解決に失敗
  • dns.failedRequest 上記以外の理由で名前解決エラー
  • tcp.timed_out TCP接続タイムアウト
  • tcp.closed TCP接続がクローズされた
  • tcp.reset TCP接続がリセットされた
  • tcp.refused TCP接続が拒否された
  • tcp.aborted TCP接続が中断された
  • tcp.address_invalid TCP接続のアドレスが正しくない
  • tcp.address_unreachable TCP接続のアドレスへ到達できない
  • tcp.failed 上記以外の理由でTCP接続が失敗した
  • tls.version_or_cipher_mismatch TLSのバージョンや暗号が合わない
  • tls.bad_client_auth_cert クライアント認証が正しくない
  • tls.cert.name_invalid 証明書の名前が正しくない
  • tls.cert.date_invalid 証明書の有効期限が正しくない
  • tls.cert.authority_invalid 証明書のauthorityが正しくない
  • tls.cert.invalid それ以外の理由で証明書が正しくない
  • tls.cert.revoked 証明書が執行している
  • tls.cert.pinned_key_not_in_cert_chain key pinningのエラー
  • tls.protocol.error TLSプロトコルエラー
  • tls.failed それ以外の理由でTLS接続が失敗した
  • http.protocol.error HTTPプロトコルのエラー
  • http.response.invalid レスポンスが空やcontent-lengthが不一致、そのたユーザエージェントがレスポンスの処理を中断
  • http.response.redirect_loop リダイレクトループ
  • http.failed 上記の理由以外でHTTPエラー
  • abandoned ユーザによる中断
  • unknown 不明

今後

Blinkの開発者MLでChromeへの導入について議論している
https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/nNji_u7BRxo

このまま行けば、Chrome 68の安定版にも入ってくるだろう