HTTP ヘッダーは名前と値のペアです。クライアント アプリケーションとバックエンド サービスはこれを使用して、リクエストとレスポンスそれぞれの追加情報を渡すことができます。次に、簡単な例をいくつか示します。
- Authorization リクエスト ヘッダーは、ユーザーの認証情報をサーバーに渡します。
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
Content-Type
ヘッダーは、送信されるリクエストまたはレスポンスのコンテンツ タイプを示します。Content-Type: application/json
HTTP ヘッダーはヘッダー フィールドの定義に応じて 1 つまたは複数の値を保持します。1 つのヘッダーが複数の値を保持する場合は、値がカンマで区切られます。次に、複数の値を保持するヘッダーの例を示します。
Cache-Control: no-cache, no-store, must-revalidate
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
X-Forwarded-For: 10.125.5.30, 10.125.9.125
Apigee Edge では、フロー変数を使用することで、どの Edge ポリシーや条件フローからでもヘッダーに簡単にアクセスできます。次に、Edge で特定のリクエスト ヘッダーまたはレスポンス ヘッダーにアクセスするのに使用できる変数の一覧を示します。
フロー変数:
message.header.header-name
request.header.header-name
response.header.header-name
message.header.header-name.N
request.header.header-name.N
response.header.header-name.N
JavaScript オブジェクト:
context.proxyRequest.headers.header-name
context.targetRequest.headers.header-name
context.proxyResponse.headers.header-name
context.targetResponse.headers.header-name
次の AssignMessage ポリシーの例は、リクエスト ヘッダーの値を読み取り、この値を変数に保存する方法を示します。
<AssignMessage continueOnError="false" enabled="true" name="assign-message-default"> <AssignVariable> <Name>reqUserAgent</Name> <Ref>request.header.User-Agent</Ref> </AssignVariable> </AssignMessage>
アンチパターン
Edge ポリシー内で HTTP ヘッダー値にアクセスし、最初の値だけを返す方法は誤りです。この方法では、複数の値を持つ HTTP ヘッダーの場合に問題が生じる可能性があります。
以下に、ヘッダーにアクセスするいくつかの例を示します。
例 1: JavaScript コードを使用して、複数の値を持つ Accept ヘッダーを読み取る
Accept
ヘッダーが、次のような複数の値を持つとします。
Accept: text/html, application/xhtml+xml, application/xml
次に、Accept
ヘッダーから値を読み取る JavaScript コードの例を示します。
// Read the values from Accept header var acceptHeaderValues = context.getVariable("request.header.Accept");
この JavaScript コードは、Accept
ヘッダーから最初の値だけを返します(この例では text/html
)。
例 2: AssignMessage または RaiseFault ポリシーで、複数の値を持つ Access-Control-Allow-Headers ヘッダーを読み取る
Access-Control-Allow-Headers
ヘッダーが、次のような複数の値を持つとします。
Access-Control-Allow-Headers: content-type, authorization
次のコードは、Access-Control-Allow-Headers
ヘッダーを設定する AssignMessage または RaiseFault ポリシーの一部分です。
<Set> <Headers> <Header name="Access-Control-Allow-Headers">{request.header.Access-Control-Request-Headers}</Header> </Headers> </Set>
このコードでは、リクエスト ヘッダー Access-Control-Allow-Headers
からの最初の値(この例では content-type
)だけを使って Access-Control-Allow-Headers
ヘッダーが設定されます。
影響
- 上記のどちらの例でも、複数の値を持つヘッダーから最初の値だけが返されることに注目してください。これらの値がその後、なんらかの関数やロジックを実行する目的で API プロキシフロー内の別のポリシーまたはバックエンド サービスで使用された場合、予期しない結果につながる可能性があります。
- リクエスト ヘッダー値が取得されてターゲット サーバーに渡される時点で、API リクエストがバックエンドによって不適切に処理され、誤った結果が生じる可能性があります。
- クライアント アプリケーションが Edge レスポンスからの特定のヘッダー値に依存している場合も、不適切な処理が行われ、誤った結果が生じる可能性があります。
ベスト プラクティス
適切な組み込みフロー変数を使用します(
request.header.header_name.values.count
、request.header.header_name.N
、response.header.header_name.values.count
、response.header.header_name.N
)。次に、JavaScript または Java Callout ポリシー内で処理を繰り返し、特定の 1 つのヘッダーからすべての値を取得します。
例: 複数の値を持つヘッダーを読み取る JavaScript コードの例
for (var i = 1; i <=context.getVariable('request.header.Accept.values.count'); i++) { print(context.getVariable('request.header.Accept.' + i)); }
たとえば上記のコードでは、
application/xml;q=0.9, */*;q=0.8
は 1 つの値のように見えます。区切り文字としてセミコロンを使ってヘッダー値を分割する必要がある場合は、
string.split(";")
を使用して値を区切ってください。RaiseFault または AssignMessage ポリシー内で、フロー変数
request.header.header_name.values
に対してsubstring()
関数を実行することで、ヘッダー内のすべての値を読み取ります。例: 複数の値を持つヘッダーを読み取る RaiseFault または AssignMessage ポリシーの例
<Set> <Headers> <Header name="Access-Control-Allow-Headers">{substring(request.header.Access-Control-Request-Headers.values,1,-1)}</Header> </Headers> </Set>