Antipola: Mengakses header HTTP multi-nilai secara tidak benar di Proxy API
Tetap teratur dengan koleksi
Simpan dan kategorikan konten berdasarkan preferensi Anda.
Anda sedang melihat dokumentasi Apigee dan Apigee hybrid.
Lihat dokumentasi
Apigee Edge.
Header HTTP adalah pasangan nilai nama yang memungkinkan aplikasi klien dan layanan backend
meneruskan informasi tambahan tentang permintaan dan respons. Beberapa contoh sederhananya adalah:
Header permintaan otorisasi meneruskan kredensial pengguna ke server:
Authorization:BasicYWxhZGRpbjpvcGVuc2VzYW1l
Header Content-Type menunjukkan jenis konten permintaan/respons yang dikirim:
Content-Type: application/json
Header HTTP dapat memiliki satu atau beberapa nilai, bergantung pada
definisi kolom header.
Header multinilai akan memiliki nilai yang dipisahkan koma. Berikut adalah beberapa contoh header yang berisi beberapa nilai:
Apigee memungkinkan developer mengakses header dengan mudah menggunakan
variabel alur
di kebijakan atau alur kondisional apa pun. Berikut adalah daftar variabel yang dapat digunakan untuk mengakses header permintaan atau respons tertentu di Apigee:
Variabel alur:
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
Objek JavaScript:
context.proxyRequest.headers.header-name
context.targetRequest.headers.header-name
context.proxyResponse.headers.header-name
context.targetResponse.headers.header-name
Berikut adalah contoh kebijakan AssignMessage yang menunjukkan cara membaca nilai header permintaan dan menyimpannya ke dalam variabel:
Mengakses nilai header HTTP dalam kebijakan Apigee dengan cara yang hanya menampilkan nilai pertama
tidak benar dan dapat menyebabkan masalah jika header HTTP tertentu memiliki lebih dari satu nilai.
Bagian berikut berisi contoh akses header.
Contoh 1: Membaca header Accept multi-nilai menggunakan kode JavaScript
Perhatikan bahwa header Accept memiliki beberapa nilai seperti yang ditunjukkan di bawah:
Kode di atas menetapkan Header Access-Control-Allow-Headers hanya dengan nilai pertama dari
header permintaan Access-Control-Allow-Headers, dalam contoh ini content-type.
Dampak
Dalam kedua contoh di atas, perhatikan bahwa hanya nilai pertama dari header multi-nilai yang ditampilkan.
Jika nilai ini kemudian digunakan oleh kebijakan lain dalam alur API Proxy atau oleh layanan backend
untuk menjalankan beberapa fungsi atau logika, hal ini dapat menyebabkan hasil atau outcome yang tidak terduga.
Saat nilai header permintaan diakses dan diteruskan ke server target, permintaan API dapat
diproses oleh backend secara tidak benar sehingga dapat memberikan hasil yang salah.
Jika aplikasi klien bergantung pada nilai header tertentu dari respons Apigee, aplikasi tersebut
juga dapat memproses dengan salah dan memberikan hasil yang salah.
Praktik Terbaik
Referensikan bentuk request.header.header_name.values.string
variabel alur untuk membaca semua nilai header tertentu.
Contoh: Contoh fragmen yang dapat digunakan di RaiseFault atau AssignMessage untuk membaca header multi-nilai
Jika Anda menginginkan akses individual ke setiap nilai yang berbeda, Anda dapat menggunakan variabel alur bawaan yang sesuai: request.header.header_name.values.count, request.header.header_name.N, response.header.header_name.values.count, response.header.header_name.N.
Kemudian, lakukan iterasi untuk mengambil semua nilai dari header tertentu dalam kebijakan JavaScript atau JavaCallout.
Contoh: Contoh kode JavaScript untuk membaca header multi-nilai
Misalnya, application/xml;q=0.9, */*;q=0.8 akan muncul sebagai dua nilai dengan kode di atas.
Nilai pertama adalah application/xml;q=0.9, dan nilai kedua adalah */*;q=0.8 .
Jika nilai header perlu dibagi menggunakan titik koma sebagai pembatas, Anda dapat menggunakan string.split(";") dalam info JavaScript untuk memisahkan nilai yang berbeda.
Sebagai alternatif, Anda dapat menggunakan fungsi substring() yang tersedia dalam
template pesan pada variabel alur request.header.header_name.values
untuk membaca semua nilai header tertentu.
Contoh: Menggunakan substring() dalam template pesan untuk membaca header multi-nilai lengkap
[[["Mudah dipahami","easyToUnderstand","thumb-up"],["Memecahkan masalah saya","solvedMyProblem","thumb-up"],["Lainnya","otherUp","thumb-up"]],[["Sulit dipahami","hardToUnderstand","thumb-down"],["Informasi atau kode contoh salah","incorrectInformationOrSampleCode","thumb-down"],["Informasi/contoh yang saya butuhkan tidak ada","missingTheInformationSamplesINeed","thumb-down"],["Masalah terjemahan","translationIssue","thumb-down"],["Lainnya","otherDown","thumb-down"]],["Terakhir diperbarui pada 2025-09-04 UTC."],[[["\u003cp\u003eThis document focuses on handling multi-valued HTTP headers within Apigee and Apigee hybrid environments, highlighting how to access and manage headers with multiple values correctly.\u003c/p\u003e\n"],["\u003cp\u003eHTTP headers can contain multiple values separated by commas, and the order of these values is significant, like in the \u003ccode\u003eX-Forwarded-For\u003c/code\u003e header where the order of the IP addresses represents network hops.\u003c/p\u003e\n"],["\u003cp\u003eAccessing multi-valued headers in Apigee using methods that only return the first value can lead to incorrect processing and unexpected results, impacting both API proxy flow and backend services.\u003c/p\u003e\n"],["\u003cp\u003eThe recommended best practice is to use the \u003ccode\u003erequest.header.header_name.values.string\u003c/code\u003e flow variable to capture all values from a multi-valued header, or access individual values using \u003ccode\u003erequest.header.header_name.N\u003c/code\u003e, where N is the index of the value.\u003c/p\u003e\n"],["\u003cp\u003eAdditionaly, the \u003ccode\u003esubstring()\u003c/code\u003e method or Javascript \u003ccode\u003esplit()\u003c/code\u003e function can be used to correctly read multi-valued headers in an Apigee flow.\u003c/p\u003e\n"]]],[],null,["# Antipattern: Access multi-value HTTP headers incorrectly in an API Proxy\n\n*You're viewing **Apigee** and **Apigee hybrid** documentation.\nView [Apigee Edge](https://docs.apigee.com/api-platform/antipatterns/multi-value-http-headers) documentation.*\n\nThe HTTP headers are the name value pairs that allow the client applications and backend services\nto pass additional information about requests and responses respectively. Some simple examples are:\n\n- Authorization request header passes the user credentials to the server: \n\n ```actionscript-3\n Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l\n ```\n- The `Content-Type` header indicates the type of the request/response content being sent: \n\n ```text\n Content-Type: application/json\n ```\n\nThe HTTP Headers can have one or more values depending on the\n[header field definitions](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html).\nA multi-valued header will have comma separated values. Here are a few examples of headers that contain multiple values:\n\n- `Cache-Control: no-cache, no-store, must-revalidate`\n- `Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8`\n- `X-Forwarded-For: 10.125.5.30, 10.125.9.125`\n\n| **Note:** The order of the multiple header values is important and must be preserved. For example with `X-Forwarded-For`, the IP addresses are listed in order of network hops from first to last.\n\nApigee allows the developers to access headers easily using\n[flow variables](/apigee/docs/api-platform/reference/variables-reference)\nin any of the policies or conditional flows. Here are the list of variables that can be used\nto access a specific request or response header in Apigee:\n\nFlow variables:\n\n- `message.header.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e\n- `request.header.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e\n- `response.header.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e\n- `message.header.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e`.`\u003cvar translate=\"no\"\u003eN\u003c/var\u003e\n- `request.header.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e`.`\u003cvar translate=\"no\"\u003eN\u003c/var\u003e\n- `response.header.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e`.`\u003cvar translate=\"no\"\u003eN\u003c/var\u003e\n\nJavascript objects:\n\n- `context.proxyRequest.headers.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e\n- `context.targetRequest.headers.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e\n- `context.proxyResponse.headers.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e\n- `context.targetResponse.headers.`\u003cvar translate=\"no\"\u003eheader-name\u003c/var\u003e\n\nHere's a sample [AssignMessage policy](/apigee/docs/api-platform/reference/policies/assign-message-policy) showing how to read the value of a request header and store\nit into a variable: \n\n```verilog\n\u003cAssignMessage continueOnError=\"false\" enabled=\"true\" name=\"assign-message-default\"\u003e\n \u003cAssignVariable\u003e\n \u003cName\u003ereqUserAgent\u003c/Name\u003e\n \u003cRef\u003erequest.header.User-Agent\u003c/Ref\u003e\n \u003c/AssignVariable\u003e\n\u003c/AssignMessage\u003e\n```\n\nAntipattern\n-----------\n\nAccessing the values of HTTP headers in Apigee policies in a way that returns only the first value\nis incorrect and can cause issues if the specific HTTP header has more than one value.\n\nThe following sections contain examples of header access.\n\n### Example 1: Read a multi-valued Accept header using JavaScript code\n\nConsider that the `Accept` header has multiple values as shown below: \n\n```actionscript-3\nAccept: text/html, application/xhtml+xml, application/xml\n```\n\nHere's the JavaScript code that reads the value from `Accept` header: \n\n```gdscript\n// Read the values from Accept header\nvar acceptHeaderValues = context.getVariable(\"request.header.Accept\");\n```\n\nThe above JavaScript code returns only the first value from the `Accept` header,\nsuch as `text/html`.\n\n### Example 2: Read a multi-valued Access-Control-Allow-Headers header in AssignMessage or RaiseFault policy\n\nConsider that the `Access-Control-Allow-Headers` header has multiple values as shown below: \n\n```carbon\nAccess-Control-Allow-Headers: content-type, authorization\n```\n\nHere's the part of code from AssignMessage or RaiseFault policy setting the `Access-Control-Allow-Headers` header: \n\n```text\n\u003cSet\u003e\n \u003cHeaders\u003e\n \u003cHeader name=\"Access-Control-Allow-Headers\"\u003e{request.header.Access-Control-Request-Headers}\u003c/Header\u003e\n \u003c/Headers\u003e\n\u003c/Set\u003e\n```\n\nThe above code sets the Header `Access-Control-Allow-Headers` with only the first value from the\nrequest header `Access-Control-Allow-Headers`, in this example `content-type`.\n\nImpact\n------\n\n1. In both the examples above, notice that only the first value from multi-valued headers are returned. If these values are subsequently used by another policy in the API Proxy flow or by the backend service to perform some function or logic, then it could lead to an unexpected outcome or result.\n2. When request header values are accessed and passed onto the target server, API requests could be processed by the backend incorrectly and hence they may give incorrect results.\n3. If the client application is dependent on specific header values from the Apigee response, then it may also process incorrectly and give incorrect results.\n\nBest Practice\n-------------\n\n1. Reference the `request.header.`**header_name**`.values.string`\n form of the flow variable to read all the values of a specific header.\n\n **Example: Sample fragment that could be used in RaiseFault or AssignMessage to read a multi-value header** \n\n ```text\n \u003cSet\u003e\n \u003cHeaders\u003e\n \u003cHeader name=\"Inbound-Headers\"\u003e{request.header.Accept.values.string}\u003c/Header\u003e\n \u003c/Headers\u003e\n \u003c/Set\u003e\n ```\n2. If you want individual access to each of the distinct values, you can use the appropriate\n built-in flow variables: `request.header.`\u003cvar translate=\"no\"\u003eheader_name\u003c/var\u003e`.values.count`,\n `request.header.`\u003cvar translate=\"no\"\u003eheader_name\u003c/var\u003e`.`\u003cvar translate=\"no\"\u003eN\u003c/var\u003e, `response.header.`\u003cvar translate=\"no\"\u003eheader_name\u003c/var\u003e`.values.count`,\n `response.header.`\u003cvar translate=\"no\"\u003eheader_name.N\u003c/var\u003e.\n\n Then iterate to fetch all the values from a specific header in JavaScript or JavaCallout policies.\n\n **Example: Sample JavaScript code to read a multi-value header** \n\n ```gdscript\n for (var i = 1; i \u003c=context.getVariable('request.header.Accept.values.count'); i++)\n {\n print(context.getVariable('request.header.Accept.' + i));\n }\n ```\n | **Note:**The comma is the delimiter between distinct header values. This approach will not split values based on other delimiters like semicolon, etc.\n\n For example, `application/xml;q=0.9, */*;q=0.8` will appear as two values with the above code.\n The first value is `application/xml;q=0.9`, and the second will be `*/*;q=0.8` .\n\n If the header values need to be split using semicolon as a delimiter, then you can use `string.split(\";\")` within the JavaScript callout to separate the distinct values.\n3. As an alternative, you can use the `substring()` function available within a\n [message template](/apigee/docs/api-platform/reference/message-template-intro) on the flow variable `request.header.`**header_name**`.values`\n to read all the values of a specific header.\n\n **Example: Use `substring()` within a message template to read a full multi-value header** \n\n ```text\n \u003cSet\u003e\n \u003cHeaders\u003e\n \u003cHeader name=\"Inbound-Headers\"\u003e{substring(request.header.Accept.values,1,-1)}\u003c/Header\u003e\n \u003c/Headers\u003e\n \u003c/Set\u003e\n ```\n\nFurther reading\n---------------\n\n- [How to handle multi-value headers in Javascript?](https://www.googlecloudcommunity.com/gc/Cloud-Product-Articles/How-to-handle-multi-value-headers-in-Javascript/ta-p/76176)\n- [IETF RFC 7230 commentary on using comma-separated lists for multi-valued HTTP header fields](https://www.rfc-editor.org/rfc/rfc7230#section-3.2.2)\n- [Request and response variables](/apigee/docs/api-platform/fundamentals/understanding-handling-request-response-data)\n- [Flow variables reference](/apigee/docs/api-platform/reference/variables-reference)"]]