Antipattern: الوصول إلى رؤوس HTTP متعددة القيم بشكل غير صحيح في خادم وكيل لواجهة برمجة التطبيقات

أنت تعرض مستندات Apigee Edge.
انتقل إلى مستندات Apigee X.
معلومات

عناوين HTTP هي أزواج قيم الاسم التي تسمح بتطبيقات العميل وخدمات الخلفية. لتمرير معلومات إضافية حول الطلبات والردود على التوالي. في ما يلي بعض الأمثلة البسيطة:

  • يمرر عنوان طلب التفويض بيانات اعتماد المستخدم إلى الخادم:
    Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
  • يشير الرأس Content-Type إلى نوع محتوى الطلب/الاستجابة الذي يتم إرساله:
    Content-Type: application/json

يمكن أن تحتوي عناوين HTTP على قيمة واحدة أو أكثر اعتمادًا على تعريفات حقول العنوان. يتضمن العنوان متعدد القيم قيمًا مفصولة بفواصل. في ما يلي بعض الأمثلة على العناوين التي تحتوي على قيم متعددة:

  • 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>

نقوش

الوصول إلى قيم عناوين HTTP في سياسات Edge بطريقة تؤدي إلى إرجاع القيمة الأولى فقط غير صحيح وقد يتسبب في حدوث مشاكل إذا كانت عناوين HTTP المحددة تحتوي على أكثر من قيمة.

تحتوي الأقسام التالية على أمثلة على الوصول إلى العنوان.

المثال 1: قراءة عنوان "قبول" متعدد القيم باستخدام رمز JavaScript

يُرجى العِلم أنّ عنوان Accept له قيم متعددة كما هو موضّح أدناه:

Accept: text/html, application/xhtml+xml, application/xml

في ما يلي رمز JavaScript الذي يقرأ القيمة من العنوان Accept:

// Read the values from Accept header
var acceptHeaderValues = context.getVariable("request.header.Accept");

يعرض رمز JavaScript القيمة الأولى فقط من العنوان Accept، مثل text/html.

المثال 2: قراءة عنوان Access-Control-Allow-Headers متعدد القيم في سياسة AssignMessage أو riseFault

يُرجى العِلم أنّ عنوان Access-Control-Allow-Headers له قيم متعددة كما هو موضّح أدناه:

Access-Control-Allow-Headers: content-type, authorization

في ما يلي جزء الرمز البرمجي الذي تم إنشاؤه من خلال إعداد سياسة AssignMessage أو RestoreFault بعنوان Access-Control-Allow-Headers:

<Set>
  <Headers>
    <Header name="Access-Control-Allow-Headers">{request.header.Access-Control-Request-Headers}</Header>
  </Headers>
</Set>

يعيّن الرمز أعلاه العنوان Access-Control-Allow-Headers مع القيمة الأولى فقط من عنوان الطلب Access-Control-Allow-Headers، في هذا المثال content-type.

التأثير

  1. في كلا المثالين أعلاه، لاحظ أنه يتم فقط إرجاع القيمة الأولى من العناوين متعددة القيم. إذا تم استخدام هذه القيم لاحقًا بواسطة سياسة أخرى في مسار الخادم الوكيل لواجهة برمجة التطبيقات أو من خلال خدمة الخلفية لأداء بعض الدوال أو المنطق، فقد يؤدي إلى نتيجة أو نتيجة غير متوقعة.
  2. عند الوصول إلى قيم عنوان الطلب وتمريرها إلى الخادم المستهدف، يمكن تحويل طلبات البيانات من واجهة برمجة التطبيقات معالجة الواجهة الخلفية بشكل غير صحيح، وبالتالي قد تظهر نتائج غير صحيحة.
  3. إذا كان تطبيق العميل يعتمد على قيم عنوان محددة من استجابة Edge، فعندئذٍ قد تعالج أيضًا بشكل غير صحيح وتعرض نتائج غير صحيحة.

أفضل الممارسات

  1. استخدِم متغيّرات التدفق المضمَّنة المناسبة: request.header.header_name.values.count request.header.header_name.N، response.header.header_name.values.count، response.header.header_name.N

    بعد ذلك، كرِّر هذه العملية لجلب جميع القيم من عنوان معيّن في سياسات وسائل شرح JavaScript أو Java.

    مثال: نموذج رمز 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 كقيمة واحدة مع الرمز أعلاه.

    إذا كنت بحاجة إلى تقسيم قيم العناوين باستخدام الفاصلة المنقوطة كمحدد، استخدِم string.split(";"). لفصلها إلى قيم.

  2. استخدام الدالة substring() على متغير التدفق request.header.header_name.values في سياسة FetchFault أو AssignMessage لقراءة كل القيم الخاصة برأس معيّن.

    مثال: نموذج FetchFault أو سياسة AssignMessage لقراءة عنوان متعدد القيم

    <Set>
      <Headers>
       <Header name="Access-Control-Allow-Headers">{substring(request.header.Access-Control-Request-Headers.values,1,-1)}</Header>
      </Headers>
    </Set>
    

محتوى إضافي للقراءة