המדיניות בנושא JavaScript

מדיניות ניתנת להרחבה

הדף הזה רלוונטי ל-Apigee ול-Apigee Hybrid.

לעיון במסמכי התיעוד של Apigee Edge

מדיניות JavaScript מאפשרת להוסיף קוד JavaScript מותאם אישית שמופעל בהקשר של תהליך ה-proxy ל-API. המדיניות הזו מאפשרת לכם להטמיע התנהגות מותאמת אישית שלא מכוסה על ידי מדיניות Apigee.

בקוד ה-JavaScript המותאם אישית, אפשר להשתמש באובייקטים, בשיטות ובמאפיינים של מודל האובייקטים של JavaScript ב-Apigee. אפשר לקבל, להגדיר ולהסיר משתנים בהקשר של זרימת ה-proxy, להפעיל לוגיקה מותאמת אישית, לבצע טיפול בשגיאות, לחלץ נתונים מבקשות או מתשובות וגם לערוך באופן דינמי את כתובת ה-URL של יעד ה-backend. אפשר גם להשתמש בפונקציות קריפטוגרפיות בסיסיות שזמינות במודל האובייקט.

מדיניות JavaScript מאפשרת לציין קובץ מקור של JavaScript להפעלה, או לכלול קוד JavaScript ישירות בהגדרות המדיניות באמצעות רכיב <Source>. בכל מקרה, קוד ה-JavaScript מופעל כשמופעל השלב שבו המדיניות מצורפת.

באפשרות של קובץ המקור, קוד המקור תמיד מאוחסן במיקום סטנדרטי בחבילת ה-proxy: apiproxy/resources/jsc. לחלופין, אפשר לאחסן את קוד המקור בקובץ משאבים ברמת הסביבה או הארגון. הוראות מפורטות מופיעות במאמר בנושא קבצי משאבים. אפשר גם להעלות JavaScript באמצעות כלי העריכה של ה-proxy בממשק המשתמש של Apigee.

קבצי מקור של JavaScript חייבים להסתיים בסיומת .js. ‫Apigee תומך ב-JavaScript שפועל במנוע JavaScript‏ Rhino 1.7.13.

ב-Apigee לא מומלץ להשתמש במדיניות JavaScript במקרים הבאים:

  • רישום ביומן. המדיניות MessageLogging מתאימה יותר לרישום נתונים בפלטפורמות רישום של צד שלישי, כמו Splunk, ‏ Sumo ו-Loggly. המדיניות הזו גם משפרת את הביצועים של proxy ל-API, כי היא מופעלת ב-PostClientFlow אחרי שהתגובה חוזרת ללקוח.
  • החלפת מדיניות Apigee. מדיניות JavaScript לא מחליפה את היכולות של מדיניות Apigee. אם היכולות שאתם צריכים זמינות במדיניות של Apigee, עדיף להשתמש במדיניות הזו במקום להטמיע פתרון JavaScript בהתאמה אישית. יכול להיות שקוד JavaScript מותאם אישית לא יתאים לביצועים ולאופטימיזציה של מדיניות Apigee.
  • כדי לבצע קריאות למערכת. מודל האבטחה לא מאפשר קריאות למערכת ממדיניות JavaScript. לדוגמה, אסור לבצע קריאות או כתיבות פנימיות במערכת הקבצים, לקבל מידע על המשתמש הנוכחי, לקבל רשימות של תהליכים או לקבל נתוני שימוש ב-CPU או בזיכרון. יכול להיות שחלק מהשיחות יפעלו, אבל הן לא נתמכות ואנחנו עשויים להשבית אותן בכל שלב. כדי לשמור על תאימות קדימה, מומלץ להימנע מביצוע הקריאות האלה בקוד.

המדיניות הזו היא מדיניות שניתנת להרחבה, והשימוש בה עשוי להשפיע על העלויות או על הניצול, בהתאם לרישיון שלכם ל-Apigee. למידע על סוגי מדיניות והשלכות השימוש, אפשר לעיין במאמר בנושא סוגי מדיניות.

דוגמאות

לשכתב את כתובת ה-URL ליעד

תרחיש שימוש נפוץ כולל חילוץ נתונים מגוף הבקשה, אחסון שלהם במשתנה של זרימת נתונים ואז שימוש במשתנה הזה של זרימת הנתונים במקום אחר בזרימת הנתונים של ה-proxy. לדוגמה, נניח שמשתמש מזין את השם שלו בטופס HTML ושולח אותו. כדי לחלץ את נתוני הטופס ולהוסיף אותם באופן דינמי לכתובת ה-URL של שירות לקצה העורפי, צריך להשתמש במדיניות JavaScript.

  1. בממשק המשתמש של Apigee, פותחים את ה-proxy שיצרתם בכלי לעריכת proxy.
  2. בוחרים בכרטיסייה פיתוח.
  3. בתפריט 'חדש', בוחרים באפשרות סקריפט חדש.
  4. בתיבת הדו-שיח, בוחרים באפשרות JavaScript ונותנים לסקריפט את השם js-example.
  5. מדביקים את הקוד הבא בעורך הקוד ושומרים את ה-proxy. האובייקט context זמין לקוד JavaScript בכל מקום בתהליך של ה-proxy. היא מקבלת קבועים ספציפיים לזרימה, קוראת ל-methods שימושיות של get/set ומבצעת פעולות אחרות. האובייקט הזה הוא חלק ממודל האובייקטים של JavaScript ב-Apigee. המשתנה target.url של Flow הוא משתנה מובנה עם גישת קריאה/כתיבה שאפשר לגשת אליו בתהליך Target Request. כשמגדירים את המשתנה הזה עם כתובת ה-URL של ה-API, ‏ Apigee קורא לכתובת ה-URL של ה-backend. הפעולה הזו משכתבת את כתובת ה-URL המקורית של היעד, שהיא כתובת ה-URL שציינתם כשיצרתם את ה-proxy (לדוגמה, http://www.example.com).
    if (context.flow=="PROXY_REQ_FLOW") {
         var username = context.getVariable("request.formparam.user");
         context.setVariable("info.username", username);
    }
    
    
    if (context.flow=="TARGET_REQ_FLOW") {
         context.setVariable("request.verb", "GET");
         var name = context.getVariable("info.username");
         var url = "http://mocktarget.apigee.net/"
         context.setVariable("target.url", url + "?user=" + name);
    }
  6. בתפריט 'מדיניות חדשה', בוחרים באפשרות JavaScript.
  7. נותנים שם למדיניות target-rewrite, מאשרים את הגדרות ברירת המחדל ושומרים את המדיניות.
  8. אחרי שבוחרים באפשרות Proxy Endpoint Preflow (זרימת נתונים לפני נקודת הקצה של ה-Proxy) בNavigator (חלונית הניווט), המדיניות מתווספת לזרימת הנתונים הזו.
  9. בחלונית הניווט, בוחרים באפשרות Target Endpoint PreFlow (זרימת נתונים לפני נקודת קצה של יעד).
  10. בחלונית הניווט, גוררים את מדיניות JavaScript לצד Request של נקודת הקצה Target בכלי לעריכת זרימת הנתונים.
  11. שמירה.
  12. כשקוראים ל-API, מחליפים את שם הארגון ואת שם ה-proxy:
curl -i -H 'Content-Type: application/x-www-form-urlencoded' -X POST -d 'user=Will' http://myorg-test.apigee.net/js-example

כדאי לבדוק את הגדרת ה-XML של מדיניות JavaScript שמשמשת בדוגמה הזו. הרכיב <ResourceURL> מציין את קובץ המקור של JavaScript להפעלה. התבנית הזו חלה על כל קובץ מקור של JavaScript: jsc://filename.js. אם קוד ה-JavaScript שלכם דורש הכללות, צריך להשתמש ברכיב <IncludeURL> אחד או יותר, כפי שמתואר בהמשך המאמר הזה.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="target-rewrite">
    <DisplayName>target-rewrite</DisplayName>
    <Properties/>
    <ResourceURL>jsc://js-example.js</ResourceURL>
</Javascript>

אחזור ערך מאפיין מ-JavaScript

אפשר להוסיף רכיב <Property> להגדרה ואז לאחזר את הערך שלו באמצעות JavaScript בזמן ריצה.

משתמשים במאפיין name של הרכיב כדי לציין את השם לגישה למאפיין מקוד JavaScript. הערך של רכיב <Property> (הערך שבין התג הפותח לתג הסוגר) הוא הערך המילולי שמתקבל ב-JavaScript.

ב-JavaScript, כדי לאחזר את ערך מאפיין המדיניות, ניגשים אליו כמאפיין של אובייקט Properties, באופן הבא:

  • מגדירים את הנכס. ערך המאפיין הוא שם המשתנה response.status.code.
    <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="JavascriptURLRewrite">
        <DisplayName>JavascriptURLRewrite</DisplayName>
        <Properties>
            <Property name="source">response.status.code</Property>
        </Properties>
        <ResourceURL>jsc://JavascriptURLRewrite.js</ResourceURL>
    </Javascript>
  • שליפת המאפיין באמצעות JavaScript. הפונקציה getVariable משתמשת בשם המשתנה שאוחזר כדי לאחזר את ערך המשתנה.
    var responseCode = properties.source; // Returns "response.status.code"
    var value = context.getVariable(responseCode); // Get the value of response.status.code
    context.setVariable("response.header.x-target-response-code", value);

הפניה לרכיב

ההפניה לרכיב מתארת את הרכיבים והמאפיינים של מדיניות JavaScript.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Javascript async="false"
        continueOnError="false" enabled="true" timeLimit="200"
        name="JavaScript-1">
    <DisplayName>JavaScript 1</DisplayName>
    <Properties>
        <Property name="propName">propertyValue</Property>
    </Properties>
    <SSLInfo>
        <Enabled>trueFalse</Enabled>
        <ClientAuthEnabled>trueFalse</ClientAuthEnabled>
        <KeyStore>ref://keystoreRef</KeyStore>
        <KeyAlias>keyAlias</KeyAlias>
        <TrustStore>ref://truststoreRef</TrustStore>
    </SSLInfo>
    <IncludeURL>jsc://a-javascript-library-file</IncludeURL>
    <ResourceURL>jsc://my-javascript-source-file</ResourceURL>
    <Source>insert_js_code_here</Source>
</Javascript>

מאפיינים של <Javascript>

< languageVersion="VERSION_1_3" Javascript name="Javascript-1" enabled="true" continueOnError="false" async="false" timeLimit="200">
מאפיין תיאור ברירת מחדל נוכחות
languageVersion

מציין את הגרסה של שפת JavaScript שבה הקוד כתוב. הערכים האפשריים הם VERSION_DEFAULT,‏ VERSION_1_0,‏ VERSION_1_1,‏ VERSION_1_2,‏ VERSION_1_3,‏ VERSION_1_4,‏ VERSION_1_5,‏ VERSION_1_6,‏ VERSION_1_7,‏ VERSION_1_8 ו-VERSION_ES6.

VERSION_DEFAULT אופציונלי
timeLimit

מציינת את משך הזמן המקסימלי (באלפיות השנייה) שסקריפט יכול לפעול. לדוגמה, אם חורגים ממגבלה של 200 אלפיות השנייה, המדיניות מחזירה את השגיאה הבאה: Javascript.policy_name failed with error: Javascript runtime exceeded limit of 200ms.

לא רלוונטי חובה

בטבלה הבאה מתוארים מאפיינים שמשותפים לכל רכיבי ההורה של המדיניות:

מאפיין תיאור ברירת מחדל נוכחות
name

השם הפנימי של המדיניות. הערך של מאפיין name יכול להכיל אותיות, מספרים, רווחים, מקפים, קווים תחתונים ונקודות. הערך הזה לא יכול לחרוג מ-255 תווים.

אפשר להשתמש ברכיב <DisplayName> כדי לתת למדיניות תווית בשם אחר בשפה טבעית בכלי לעריכת פרוקסי בממשק הניהול.

לא רלוונטי חובה
continueOnError

מגדירים את הערך false כדי להחזיר שגיאה אם המדיניות נכשלת. זו התנהגות צפויה ברוב המדיניות.

הגדרה ל-true מאפשרת להמשיך את הביצוע של התהליך גם אחרי שמדיניות נכשלת. מידע נוסף:

FALSE אופציונלי
enabled

מגדירים את המדיניות למצב true כדי לאכוף אותה.

מגדירים את הערך false כדי להשבית את המדיניות. המדיניות לא תיאכף גם אם היא תישאר מצורפת לזרימה.

TRUE אופציונלי
async

המאפיין הזה הוצא משימוש.

FALSE הוצא משימוש

אלמנט <DisplayName>

משתמשים בו בנוסף למאפיין name כדי לתת למדיניות שם אחר בשפה טבעית, לסימון המדיניות בכלי לעריכת פרוקסי בממשק המשתמש לניהול.

<DisplayName>Policy Display Name</DisplayName>
ברירת מחדל

לא רלוונטי

אם לא מציינים את הרכיב הזה, המערכת משתמשת בערך של המאפיין name של המדיניות.

נוכחות אופציונלי
סוג String

אלמנט <IncludeURL>

מציין קובץ של ספריית JavaScript לטעינה כתלות בקובץ ה-JavaScript הראשי שצוין באמצעות הרכיב <ResourceURL> או <Source>. המדיניות מעריכה את הסקריפטים לפי הסדר שבו הם מופיעים במדיניות. הקוד יכול להשתמש באובייקטים, בשיטות ובמאפיינים של מודל האובייקטים של JavaScript.

אפשר לכלול יותר ממשאב תלות אחד ב-JavaScript באמצעות עוד רכיבי <IncludeURL>.

<IncludeURL>jsc://my-javascript-dependency.js</IncludeURL>
ברירת מחדל: ללא
נוכחות: אופציונלי
סוג: String

אלמנט <Property>

מציין מאפיין שאפשר לגשת אליו מקוד JavaScript בזמן ריצה.

<Properties>
    <Property name="propName">propertyValue</Property>
</Properties>
ברירת מחדל: ללא
נוכחות: אופציונלי
סוג: String

מאפיינים

מאפיין תיאור ברירת מחדל נוכחות
name

מציין את שם הנכס.

לא רלוונטי חובה

דוגמה

אפשר לראות דוגמה בקטע דוגמאות.

אלמנט <ResourceURL>

מציינים את קובץ ה-JavaScript הראשי שמופעל בתהליך העבודה של ה-API. אפשר לאחסן את הקובץ הזה בהיקף של שרת ה-proxy ל-API (בקטע /apiproxy/resources/jsc בחבילת שרת ה-proxy ל-API או בקטע Scripts בחלונית Navigator של כלי העריכה של שרת ה-proxy ל-API). לחלופין, אפשר לאחסן אותו בהיקף של הארגון או הסביבה כדי לעשות בו שימוש חוזר בכמה שרתי proxy ל-API, כמו שמתואר במאמר ניהול משאבים. הקוד יכול להשתמש באובייקטים, בשיטות ובמאפיינים של מודל האובייקטים של JavaScript.

<ResourceURL>jsc://my-javascript.js</ResourceURL>
ברירת מחדל: ללא
נוכחות: צריך לציין <ResourceURL> או <Source>. אם הוגדרו גם <ResourceURL> וגם <Source>, המערכת תתעלם מהמדיניות <ResourceURL>.
סוג: String

דוגמה

אפשר לראות דוגמה בקטע דוגמאות.

רכיב <Source>

אפשר להוסיף JavaScript ישירות להגדרת ה-XML של המדיניות. קוד ה-JavaScript שמוסיפים מופעל כשהמדיניות מופעלת בתהליך של ה-API.

ברירת מחדל: ללא
נוכחות: צריך לציין <ResourceURL> או <Source>. אם הוגדרו גם <ResourceURL> וגם <Source>, המערכת תתעלם מהמדיניות <ResourceURL>.
סוג: String

דוגמה

<Javascript name='JS-ParseJsonHeaderFullString' timeLimit='200' >
  <Properties>
    <Property name='inboundHeaderName'>specialheader</Property>
    <Property name='outboundVariableName'>json_stringified</Property>
  </Properties>
  <Source>
var varname = 'request.header.' + properties.inboundHeaderName + '.values.string';
var h = context.getVariable(varname);
if (h) {
  h = JSON.parse(h);
  h.augmented = (new Date()).valueOf();
  var v = JSON.stringify(h, null, 2) + '\n';
  // further indent
  var r = new RegExp('^(\S*)','mg');
  v= v.replace(r,'    $1');
  context.setVariable(properties.outboundVariableName, v);
}
  </Source>
</Javascript>

אלמנט <SSLInfo>

מציינת את המאפיינים שמשמשים להגדרת TLS לכל המופעים של לקוח HTTP שנוצרו על ידי מדיניות JavaScript.

    <SSLInfo>
        <Enabled>trueFalse</Enabled>
        <ClientAuthEnabled>trueFalse</ClientAuthEnabled>
        <KeyStore>ref://keystoreRef</KeyStore>
        <KeyAlias>keyAlias</KeyAlias>
        <TrustStore>ref://truststoreRef</TrustStore>
    </SSLInfo>
ברירת מחדל: ללא
נוכחות: אופציונלי
סוג: String

תהליך ההגדרה של TLS ללקוח HTTP זהה לתהליך ההגדרה של TLS ל-TargetEndpoint או ל-TargetServer. מידע נוסף מופיע במאמר בנושא אפשרויות להגדרת TLS.

שימוש ב-JavaScript לטיפול בשגיאות

אפשר להשתמש במדיניות JavaScript כדי לטפל בשגיאות ולהחזיר אותן. בקהילת Apigee אפשר לקרוא דיון בנושא הדרך הנכונה להחזיר שגיאה ממדיניות JavaScript. הערה: הפוסטים והתגובות בקהילה לא בהכרח מייצגים את השיטות המומלצות של Apigee.

ניפוי באגים בקוד מדיניות JavaScript

כדי להציג מידע על ניפוי באגים בחלונית הפלט של העסקאות בכלי לניפוי באגים, משתמשים בפונקציה print(). לפרטים ודוגמאות, אפשר לעיין במאמר ניפוי באגים ב-JavaScript באמצעות הצהרות print()‎.

כדי לראות את הצהרות ההדפסה בכלי לניפוי באגים:

  1. פותחים את כלי הניפוי באגים ומתחילים סשן מעקב לשרת proxy שמכיל את מדיניות JavaScript.
  2. מתקשרים לשרת ה-proxy.
  3. בכלי לניפוי באגים, לוחצים על מדיניות JavaScript ואז על הכרטיסייה מאפיינים כדי לראות את המאפיין stepExecution-stdout שמציג את הפלט של הצהרת ההדפסה.

    פלט מהכרטיסייה &#39;מאפיינים&#39; בכלי לניפוי באגים, שבו מוצגות הצהרות הדפסה.

  4. הדוחות של ההדפסות יופיעו בחלונית הזו.

משתני Flow

כברירת מחדל, המדיניות הזו לא מאכלסת משתנים. עם זאת, אפשר להגדיר משתני זרימה ולקבל אותם בקוד JavaScript באמצעות קריאה לשיטות באובייקט context. לדוגמה:

context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"))

האובייקט context הוא חלק ממודל האובייקטים של JavaScript ב-Apigee.

הפניה לשגיאה

本部分介绍当此政策触发错误时返回的故障代码和错误消息,以及由 Apigee 设置的故障变量。在开发故障规则以处理故障时,请务必了解此信息。如需了解详情,请参阅您需要了解的有关政策错误的信息处理故障

运行时错误

政策执行时可能会发生这些错误。

故障代码 HTTP 状态 原因 修复
steps.javascript.ScriptExecutionFailed 500 JavaScript 政策可能会抛出许多不同类型的 ScriptExecutionFailed 错误。 常见的错误类型包括:RangeErrorReferenceErrorSyntaxErrorTypeErrorURIError
steps.javascript.ScriptExecutionFailedLineNumber 500 JavaScript 代码中出现错误。请参阅故障字符串了解详情。 不适用
steps.javascript.ScriptSecurityError 500 JavaScript 执行时出现安全错误。请参阅故障字符串了解详情。 不适用

部署错误

在您部署包含此政策的代理时,可能会发生这些错误。

错误名称 原因 修复
InvalidResourceUrlFormat 如果 JavaScript 政策的 <ResourceURL><IncludeURL> 元素中指定的资源网址格式无效,则 API 代理的部署将失败。
InvalidResourceUrlReference 如果 <ResourceURL><IncludeURL> 元素引用了不存在的 JavaScript 文件,则 API 代理的部署将失败。引用的源文件必须存在于 API 代理、环境或组织级别。
WrongResourceType 如果 JavaScript 政策的 <ResourceURL><IncludeURL> 元素引用除 jscJavaScript 文件)以外的任何资源类型,则会在部署期间出现此错误。
NoResourceURLOrSource 如果未声明 <ResourceURL> 元素或此元素内未定义资源网址,则 JavaScript 政策的部署可能会失败,并显示此错误。<ResourceURL> 元素是必需元素。或者,声明了 <IncludeURL> 元素,但未在此元素中定义资源网址。<IncludeURL> 元素是可选的,但如果声明,则必须在 <IncludeURL> 元素中指定资源网址。

故障变量

当此政策在运行时触发错误时,将设置这些变量。如需了解详情,请参阅您需要了解的有关政策错误的信息

变量 其中 示例
fault.name="fault_name" fault_name 是故障名称,如上面的运行时错误表中所列。故障名称是故障代码的最后一部分。 fault.name Matches "ScriptExecutionFailed"
javascript.policy_name.failed policy_name 是抛出故障的政策的用户指定名称。 javascript.JavaScript-1.failed = true

错误响应示例

{
  "fault": {
    "faultstring": "Execution of SetResponse failed with error: Javascript runtime error: "ReferenceError: "status" is not defined. (setresponse.js:6)\"",
    "detail": {
      "errorcode": "steps.javascript.ScriptExecutionFailed"
    }
  }
}

故障规则示例

<FaultRule name="JavaScript Policy Faults">
    <Step>
        <Name>AM-CustomErrorResponse</Name>
        <Condition>(fault.name Matches "ScriptExecutionFailed") </Condition>
    </Step>
    <Condition>(javascript.JavaScript-1.failed = true) </Condition>
</FaultRule>

סכימה

כל סוג מדיניות מוגדר על ידי סכימת XML‏ (.xsd). לעיון, סכימות מדיניות זמינות ב-GitHub.

נושאים קשורים

מאמרים בקהילת Apigee

אפשר למצוא מאמרים קשורים בקהילת Apigee: