0

WebExtensionでwebRequest-APIを使用して、クライアントからのリクエストを監視しています。これは非常にうまくいきますが、APIはリダイレクトの場合には期待どおりに動作しません。webRequest APIリダイレクトは親リクエストのhttpメソッドを使用します

POSTが発行され、302 FOUNDと新しい場所が返されます。このリダイレクトに続いて(Firefox 57、他のバージョンや他のブラウザ - たとえばChrome - 同じように動作します)、新しい場所にGETが発行されます。

enter image description here

残念なことにWebRequestクラス-APIは、異なる動作:それはGETでなければならないのに対し、それは、あまりにも、(正確である)第POSTをトレースが、POSTとして第2の要求を処理するよりも。これは、APIが私のブラウザで実際に行ったことのようなものをトレースするため、重大な問題です。

このシナリオ(ブラウザ部分)は、this link to surfnet.nlに従い、IDPフォームを選択することで再現できます(例:Academisch Medisch Centrum)。

ですから、長いストーリー:なぜwebRequest-APIはブラウザの動作とは異なる動作をしますか?ブラウザの動作を正確に追跡する方法はありますか?

興味深いことにWebRequestクラス-APIは、正しくregarding the documentationそれを行う可能性があります:

仕様は、すべてのユーザーではない方法を必要とし、リダイレクトが行われた場合、本体は、を変更してはならない、場合でも、 - エージェントはここに準拠します [ブラウザは明らかにメソッドを変更します!]、バグのあるソフトウェアが見つかることがあります。したがって、GETまたはHEADメソッドに対する応答としてのみ302コードを設定し、その場合はメソッドの変更が明示的に禁止されているため、代わりに307一時リダイレクトを使用することをお勧めします。 メソッドをGETに変更する場合は、303を使用します。代わりに「その他」を参照してください。


EDITは:ブラウザは、原因歴史的な理由に302の方法を変更した場合、それはRFC 2616矛盾さえカントーとして それは

質問は残っています。webRequest-APIを同じように動作させるにはどうすればよいですか?

+0

https://bugzilla.mozilla.org – Smile4ever

+0

でバグを開いてください。@ Smile4everあなたのコメントをありがとうございますが、実際にはバグではないと思います。 – khlr

+0

あなたの質問への回答を望むなら、それは実際にはバグではないと思っても、おそらく質問するのに最適な場所です。 – Smile4ever

答えて

0

は興味がある人のために、私は次のようになってしまった:

ドキュメントはthisredirectUrl)に私を聞かせて:

[...]リダイレクトアクションによって開始されたリダイレクトは、リダイレクトに対して元のリクエストメソッドを使用します。ただし、リダイレクトがonHeadersReceivedステージで開始された場合、リダイレクトはGETメソッドを使用して発行されます。 [...]

上記の文は私にいくつかの希望を与えたが、そのリダイレクト要求のmethodがまだPOSTと名付けられた...

だから私は大体このような何かにコードを更新します:

// Keep track of all requests issued so far and their responses 
var httpRequests = []; 

// Redirected requests come in with their originating parents' ID 
browser.webRequest.onBeforeRequest.addListener(request => { 
    // Check if the request is a redirect 
    var isRedirected = function(requestId) { 
     var parentRequest = httpRequests.find(r => r.req.requestId === requestId); 
     if (parentRequest != null && parentRequest.res != null && parentRequest.res.statusCode === 302) { 
      return true; 
     } 
     return false; 
    }; 

    // The webRequest-API seems to keep the HTTP verbs which is correct in resepct to RFC 2616 but 
    // differs from a typical browser behaviour which will usually change the POST to a GET. So do we here... 
    if (request.method === 'POST' && isRedirected(request.requestId)) { 
     console.log(`Redirected 302-request '${request.requestId}' is a POST but is here changed to a GET to conform to browser behaviour...`); 
     request.method = 'GET'; 
    } 

    // Store the request 
    var entry = { 
     id: id, 
     req: request 
    }; 
    httpRequests.push(entry); 
}); 

browser.webRequest.onHeadersReceived.addListener(response => { 
    // Store the response alongside the request 
    var entry = httpRequests.find(req => req.id === response.requestId); 
    entry.res = response; 

    // If it turns out that a request should be redirected... 
    if (response.statusCode === 302) { 
     var location = response.responseHeaders.find(header => header.name.toLowerCase() === "location"); 
     console.log(`Redirecting request '${id}' to new location '${location.value}'...`); 

     // The new location is set as redirectUrl, which results in a new invocation of onBeforeRequest with 
     // the current requestId 
     return { 
      redirectUrl: location.value 
     }; 
    } 
}); 

どうしますか?

  1. と言ってくださいonBeforeRequestは、新しいリクエスト2640をPOSTとして受信します。
  2. onHeadersReceivedは、この要求を新しい場所(302)にリダイレクトする必要があるという応答を取得します。
  3. 上記のコードでは、redirectUrlをその新しい場所に設定しています。
  4. onBeforeRequestが再度トリガされます。 webRequest-APIは同じrequestIdをそれに渡します(2640)。
  5. このコードでは、このリクエストの親があるかどうかをチェックします。この場合はtrueです。
  6. (まだPOSTである)メソッドは、GETに変更されます。

リクエストライフサイクルについては、図in the docsをご覧ください。

関連する問題