מאמר 1 : תוספות בצד השרת / לינדה קול
בעזרת תוספות בצד השרת (SSI - Server Side Include ) ניתן לשנות אתר אינטרנט בעל 1000 עמודים תוך מספר דקות!
(יש לשים לב שלא כל פקודות SSI יפעלו בכל שרת - זה תלוי בסוג השרת ובקונפיגורציה שלו).
1.1.1 מהן תוספות-שרת (SSI) ומה ניתן לעשות איתם?
תוספות-שרת( SSI) הוצגו לראשונה בשרת NCSA, אפאצ'י התקדמה שלב אחד נוסף ליצירת XSSI. תוספות השרת פועלות על רוב השרתים אך לא על כולם (למשל, הם לא יפעלו ב - CERN ). תוספת-שרת היא פקודה או פקודה בתוך קובץ HTML באמצעות שורת הערה. בעזרת פקודת SSI פשוטה, ניתן לעדכן עיצוב של האתר כולו, להוסיף באופן דינמי את הזמן והתאריך הנוכחיים, או את תאריך העדכון האחרון של הקובץ, לבצע הרצת המעטפת (shell) ו - CGI scripts ועוד. תוספות השרת מהוות יתרון גדול למפתחי רשת בעלי אמצעים מוגבלים וזמן מוגבל, הצריכים לטפל במיליוני עמודים.
1.1.2 כיצד להריץ את תוספות השרת?
אפשר "להריץ" את תוספות השרת ע"י עריכת קבצי הקונפיגורציה של השרת או ע"י הוספת קובץ htaccess. לספריה אליה רוצים להכניס את התוספת:
1.1.2.1 קונפיגורציה של השרת
אם קיימת גישה לקבצי הקונפיגורציה של השרת, ניתן לאפשר הרצת SSI באמצעות עריכת acess.conf ו- srm.conf. יש להתחבר לשרת (באמצעות TELNET ) ולחפש את הספריה בה מצויים קבצי הקונפיגורציה (כנראה /usr/local/etc/httpd/conf ).
בעזרת עורך טקסט, יש לפתוח את srm.conf ולאתר את השורות הבאות:
|
# If you want to use server side includes, or CGI outside
# ScriptAliased directories, uncomment the following lines.
#AddType text/x-server-parsed-html .shtml
#AddType application/x-httpd-CGI .CGI
|
|
קיימת אפשרות ששורות אלה לא נמצאות. במקרה כזה יש למצוא שתי שורות שמתחילות
ב- AddType. יש לבטל את ה - # שלפניהן. יש לשמור את השינויים שבוצעו ולעבור
ל - access.conf. כעת, יש לאתר את הקטע בקובץ שמטפל בזיהוי הספרייה אשר תוגדר
כספריית השורש. קטע זה יהיה כנראה דומה לקטע להלן אם כי יתכן שיהיו לו הגדרות אחרות בין תגי ה- <Directory> וה - <Directory/>:
|
# This should be changed to whatever you set DocumentRoot to.
<Directory /usr/local/etc/httpd/htdocs>
# This may also be "None", "All", or any combination of "Indexes",
# "Includes", or "FollowSymLinks"
Options Indexes FollowSymLinks Includes
</Directory>
|
|
את הספרייה יש לשנות לפי ספריית השורש של המשתמש וכן במקום האפשרויות בשורה השלישית יכול לבוא "All" או "None" או כל צירוף אחר של האפשרויות השונות. אם לא רוצים לאפשר הרצת scripts או פקודות shell, יש להוסיף IncludesNOEXEC
לשורת הבחירות (options line).
פקודה זו תאפשר הרצת תוספות (SSI) אך לא CGI ופקודות shell.
הערה: בגרסת האפאצ'י האחרונה קיים קובץ אחד הכולל את כל הגדרות הקונפיגורציה ושמו httpd.conf. את כל העריכה לעיל ניתן לבצע בקובץ זה.
1.1.2.2 יצירת קובץ .htaccess
אם אין גישה לקבצי הקונפיגורציה של השרת ניתן ליצור קובץ באמצעות עורך טקסט כלשהו ולקרוא לו: htaccess. (לא לשכוח את הנקודה - היא מורה לשרת שזהו קובץ נסתר). יש
להוסיף את 3 השורות הבאות לקובץ זה:
|
Options Indexes FollowSymLinks Includes
AddType application/x-httpd-CGI .CGI
AddType text/x-server-parsed-html .shtml
|
|
יש להעלות קובץ זה לספרייה, עליה רוצים להגן. כל תת הספריות הכלולות בספרייה זו מוגנות גם הן. אם רוצים למנוע הרצת פקודות shell או CGI בספריות מסוימות בלבד, ניתן להוסיף IncludesNOEXEC בשורת הבחירות של קובץ htaccess..
1.1.3 מדוע יש צורך ב - shtml. ? מדוע אי אפשר להשתמש ב - html. ?
קובץ הכולל תוספות חייב לעבור חלוקה וניתוח ע"י השרת. דרישה זו מעמיסה על השרת, אך סביר שלא תורגש האטה בזמן הטעינה (אלא אם האתר זוכה למליוני מבקרים בכל יום).
אם לא משתמשים בתוספות, כדי להוסיף את הכותרות העליונות והתחתונות לאתר כולו, אין צורך לבצע ניתוח ומעבר על כל עמוד ועמוד. אם ברצוננו להוסיף כמה תוספות לעמודים מסוימים בלבד, נגדיר להם סיומת shtml. והשרת יבצע חלוקה וניתוח רק של עמודים אלה.
מאידך, אם ברשותנו אתר קיים בעל עמודים רבים ונרצה להשתמש בתוספות כדי להוסיף כותרות עליונות ותחתונות - אזי במקום לשנות את כל סיומות הקבצים לסיומת shtml., ניתן להוסיף את השורה הבאה לקובץ htaccess. :
AddType text/x-server-parsed-html .html.
כך נעבור על כל העמודים, נחלקם וננתחם.
הפורמט של פקודות SSI הוא: <--"directive parameter="value#--!>.
אך מה משמעותו? מהי פקודה ( directive ), מהו פרמטר ( parameter ) וכיצד יודעים מהו
הערך (value )?
פקודה היא הוראה למחשב (במקרה שלנו - שרת ) לבצע מטלה מסוימת.
הפרמטר הוא האובייקט עליו תתבצע ההוראה.
הערך הוא התוצאה המבוקשת מן המטלה שבוצעה על הפרמטר.
פקודת SSI מתחילה ב - #--!>. יש לשים לב שאין רווח בין הסימנים --!> לבין ה - #. אם מוסיפים רווח לפני ה - #, השרת יניח שפקודת ה - SSI היא הערה ולכן הוא לא ידפיס דבר, אפילו לא הודעת שגיאה. לאחר מכן, כותבים אחת מששת הפקודות האפשריות ואחריה פרמטר, סימן שווה (=) והערך, תחום במרכאות. אסור שיהיו רווחים משני צדי סימן ה - =. את הערך יש למסגר במרכאות כפולות ("). בסיום מחרוזת הערך יש לשים רווח ואחריו, תג הסגירה ( <--).
|
פקודות | פרמטרים מתאימים |
config | errmsg, timefmt, sizefmt |
include | virtual, file |
echo | var |
fsize | file |
flastmod file | file |
exec | cmd,cgi |
|
פקודה זו משנה את הגדרות ברירת המחדל של SSI.
errmsg מגדיר הודעת שגיאה ומציבה כברירת מחדל חדשה. תוספת זו חייבת לבוא לפני תוספות אחרות בקובץ ה - html, ע"מ שתחזיר את הודעת השגיאה המתוקנת. כל תוספת שמופיעה לפני errmsg תחזיר את הודעת השגיאה הקודמת ולא את ההודעה החדשה שהגדיר המשתמש. השגיאה נרשמת ב - log error של השרת.
|
<!--#config errmsg="Another include messed up.
Please email webmaster@mydomain.com -->
|
|
timefmt מגדיר את הפורמט לכתיבת זמן ותאריכים. ע"מ שתפעל, הפקודה
config timefmtחייבת לבוא לפני פקודת echo.
זוהי מחרוזת התואמת לקריאה לספריית strftime הקיימת ברוב הגרסאות של UNIX.
לדוגמא: |
<!--#config timefmt="%A, %B %d, %Y"-->
<!--#echo var="LAST_MODIFIED" -->
|
|
מופיע כך: Wednesday, April 12, 2000.
כדי לקבל הסבר מהיר ופשוט יש לקרוא את טבלת
TIME/Dates Format.
sizefmt מגדיר האם הקובץ יוצג בבתים (bytes) או קילובתים (KB) או מגהבתים (MB)
כדי להציג בבתים, יש להשתמש בערך "bytes". כדי להציג בקילובתים (KB) או מגהבתים
(MB), יש לקבוע את הערך "abbrev".
ע"מ שתפעל, הפקודה config sizefmt חייבת לבוא לפני פקודת fsize.
לדוגמא: |
<!--#config sizefmt="bytes" -->
<!--#fsize file="index.html" -->
|
|
תוספת (include) מכניסה טקסט (או תמונות) של מסמך אחר לתוך המסמך שעבר
חלוקה וניתוח. מפתחים ותיקים נתקלים בבעיות, לעיתים קרובות, כמו: הצורך לשנות עמודים מרובים בכל פעם שמשנים את עיצוב האתר, הכותרות או הניווט. גם אם יורשים אתר אינטרנט בעל 2000 עמודים - יש בעיה גדולה לבצע בו שינויים. לכן התוספות ( include ) הן כ"כ שימושיות. משנים רק קובץ אחד, ה-include, וכל האתר מתעדכן ברגע!
ל- include שני פרמטרים. אם משתמשים בפרמטר לא נכון לעדכון אתר בעל ספריות מרובות, יתקבלו הודעות שגיאה מרובות במקום עדכון מיידי.
virtual מגדיר נתיב וירטואלי למסמך על השרת. לדוגמא:
|
<!--#include virtual="/includes/header.html" -->
|
|
כדי לשמור על הסדר, ניתן ליצור ספרייה ברמת השורש בשם includes ושם לשמור את כל קבצי ה-include . הפרמטר include מציין לשרת שיש לכלול קובץ וירטואלי (virtual) - קובץ הממוקם בספרייה שאינה הספרייה בה מצוי הקובץ המחולק והמנותח. הערך (value) מציין לשרת שהתוספת מצויה בספרייה בשם includes, שנמצאת ברמת השורש. באמצעות שיטה זו ניתן ליצור את כל עמודי ה - HTML בעזרת אותו include, ניתן לשמור אותם בספריות ותתי-ספריות שונות והשרת יוכל למצוא את ה-include - ללא קבלת הודעות שגיאה.
הערה: אם משתמשים בספרייה אחת לכל ה-includes, רצוי להגן עליה מפני spiders (כלי של מנגנוני החיפוש באינטרנט המעדכן את מסד הנתונים שלו ע"י שיטוט ברשת וחיפוש אחרי אתרים חדשים) ו- bots (רובוט, תכנה המדמה משתמש במשחק MUD או בשיחת ועידה באינטרנט) בעזרת קובץ robots exclusion
, במיוחד אם מגדירים סיומת html.
השארת הספרייה פתוחה ולא מוגנת תגרום לכך שהקבצים בספריה ימוינו.
אם רוצים להוסיף תגי META, ו - <DOCTYPE< TITLE לדפים (וזה בהחלט מומלץ), תתגלה בעיה אחרת. אם מוסיפים קובץ header יחיד לכל הדפים, אזי כולם יקבלו את אותם תגי TITLE ו - META. אך, אפשר לעקוף בעיה זו ע"י שימוש בשתי פקודות include - אחת עבור הנתונים מעל ה - TITLE ואחת עבור כל מה שנמצא מתחת לתגי META.
תוספת 1#, או header1, כוללת את תגי ה - html וה - head הפותחים ואת הצהרת
ה - doctype, בצורה הבאה:
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
|
|
תוספת 2# או header2, כוללת את תג ה - HEAD הסוגר ואת תג ה - BODY וכן את כל מה שרוצים שיופיע ב - header, אך לא התוכן העיקרי של הדף, בצורה הבאה:
|
</HEAD>
<BODY bgcolor="#FFFFFF">
...all HTML, text, navigation or
images that make up the page header...
|
|
מסמך ה - HTML כולל את ה-include ל - header #1, כותרת (title), הנתיב המלא לגליון הסגנון (style sheet), תגי META וה-include ל - header #2.
התוכן העיקרי של העמוד יופיע מתחת ל-include עבור header2.
עבור הודעות על זכויות יוצרים או כל דבר אחר שרוצים לכלול ניתן להוסיף כותרת תחתונה אחרי התוכן העיקרי. וכך, תבנית עמוד האינטרנט תיראה כך (בשינויים קלים):
|
<!--#include virtual="/includes/header1.html" -->
<TITLE>Your Page Title</TITLE>
<LINK rel = STYLESHEET
href = "http://domain.com/styles/my.css"
Type = "text/css" >
<META NAME = "Description"
CONTENT = " Description of page">
<META NAME = "Keywords"
CONTENT = "keywords for page"
>
<!--#include virtual="/includes/header2.html" -->
....plug main page content in here...
<!--#include virtual="/includes/footer.html" -->
|
|
include של כותרות עליונות ותחתונות יכולות לחסוך המון שעות עבודה בעדכון אתרים.
אם רוצים להכניס תוכן דינמי בכותרת הזאת, כמו למשל הצגת תאריך העדכון האחרון יש לשמור את ה-includes בעזרת סיומת HTML ואז ניתן להוסיף include בתוך include!
file מגדיר את שם הנתיב יחסית לספרייה הנוכחית. אי אפשר להשתמש ב- /.. בשם נתיב זה וכן אסור להשתמש בנתיבים אבסולוטיים.
שיטה נוספת היא:
|
<!--#include file="header.html" -->
|
|
בשיטה זו, נזדקק לקובץ בשם header.html בכל ספרייה אך זה ממש לא יעיל, כמעט כמו עדכון כל דף, בכל פעם שמבצעים שינויים באתר.
מצד שני, אם רוצים להשתמש בקובץ ה-include לעדכן (למשל) הודעת חדשות שמופיעה רק בעמוד אחד, שיטה זו עשויה להועיל. כמו למשל, אם לא מעונינים לאפשר למישהו שאינו מיומן ב - HTML לעדכן את הקטע החדשותי של דף האינדקס, אבל כן לאפשר לו לעדכן קובץ טקסט נפרד אשר ייכלל מאוחר יותר במסמך ה- HTML.
1.5 הדפסת משתני סביבה בעזרת echo
echo מדפיס את הערך של אחד ממשתני הסביבה:
DOCUMENT_NAME מדפיס את שם הקובץ של המסמך הנוכחי, בצורה הבאה:
|
<!--#echo var="DOCUMENT_NAME" -->
displays as:
index.html
|
|
DOCUMENT_URI מדפיס את הנתיב הוירטואלי למסמך הנוכחי, בצורה הבאה:
|
<!--#echo var="DOCUMENT_URI" -->
displays:
/YourDirectory/YourFilename.html
|
|
יתרון נוסף של ה-include הוא שבמקום להציג את ה - URL המלא של העמודים בכל עמוד ועמוד באתר, ניתן לכתוב את שם ה - domain לפני ה-include , וכך יוצג ה- URL המלא של כל עמוד. נעשה זאת בצורה הבאה:
|
http://YourDomain<!--#echo var="DOCUMENT_URI" -->
|
|
QUERY_STIRNG_UNESCAPED - גרסה של כל שאילתת חיפוש שהמשתמש שלח, כשכל תווי Shell המיוחדים תחומים ב - /.
נעשה זאת בצורה הבאה:
|
<!--#echo var="QUERY_STRING_UNESCAPED" -->
|
|
DATE LOCAL - תאריכים וזמנים כפופים לאזור השעון של השרת, אלא אם קובעים את הקונפיגורציה של השרת להציג אזור-זמן אחר.
ברירת המחדל של פלט DATE_LOCAL אינה מספקת ומוצגת בצורה רעה אך לא צריך להסתפק בברירת המחדל.
ע"י שילוב המשתנה עם הפרמטר config timefmt, ניתן להגדיר כמעט כל פלט מבוקש.
הדוגמא הבאה מציגה את פלט ברירת המחדל של DATE_LOCAL:
|
<!--#echo var="DATE_LOCAL" -->
displays as:
Saturday, 15-Apr-2000 12:24:42 MDT
|
|
ע"מ לקבל פלט רצוי ונעים לעין יש להשתמש בפקודת ה - config. יש להוסיף טקסט ל-include כדי לקבל פלט בצורת משפט הגיוני, במקום הצגת המידע בצורה פשוטה ופרימיטיבית. נעשה זאת בצורה הבאה:
|
<!--#config timefmt="%A, the %d of %B, in the year %Y" -->
<!--#echo var="DATE_LOCAL" -->
displays as:
Saturday, the 15 of April, in the year 2000
|
|
DATE_GMT - פקודה זו פועלת כמו DATE_LOCAL, אלא שהזמן המוחזר הוא לפי שעון גריניץ'. נעשה זאת בצורה הבאה:
|
<!--#echo var="DATE_GMT" -->
|
|
LAST_MODIFIED - מראה את התאריך האחרון בו עודכן הקובץ הנוכחי. ע"י הוספת השורה הבאה לדפי ה -HTML , ידאג ה -SSI לעדכן את התאריך האחרון בו שונה הקובץ. נעשה זאת בצורה הבאה:
|
<!--#echo var="LAST_MODIFIED" -->
|
|
בנוסף למשתני סביבה מסוג SSI, ישנה גם קבוצת משתני סביבה של CGI:
SERVER_SOFTWARE - השם והגרסה של תוכנת השרת.
|
<!--#echo var="SERVER_SOFTWARE" -->
|
|
SERVER_NAME
שם המארח (host) של השרת: כינוי DNS או כתובת IP .
|
<!--#echo var="SERVER_SOFTWARE" -->
|
|
GATEWAY_INTERFACE - הגרסה המתוקנת של מפרט ה - CGI, לה מתאים השרת.
|
<!--#echo var="GATEWAY_INTERFACE" -->
|
|
SERVER_PROTOCOL - השם והגרסה המתוקנת של פרוטוקול המידע המלווה בקשה זו, כלומר HTTP/1.0.
|
<!--#echo var="SERVER_PROTOCOL" -->
|
|
SERVER_PORT - ה - port דרכו השרת עונה.
|
<!--#echo var="SERVER_PORT" -->
|
|
REQUEST_METHOD - השיטה לפיה הלקוח ביקש את המסמך.
ב - HTTP, הכוונה ל - GET, HEAD, POST .
|
<!--#echo var="REQUEST_METHOD" -->
|
|
PATH_INFO - ניתן לגשת ל- scripts לפי שם הנתיב הוירטואלי שלהם (יחסית לספריית הבסיס) ואחריו מידע נוסף שניתן על ידי הלקוח.
|
<!--#echo var="PATH_INFO" -->
|
|
PATH_TRANSLATED - השרת מתרגם את PATH_INFO ממיקום וירטואלי למיקום פיזי .
|
<!--#echo var="PATH_TRANSLATED" -->
|
|
SCRIPT_NAME - זהו הנתיב הוירטואלי ל - script שעובר הרצה.
|
<!--#echo var="SCRIPT_NAME" -->
|
|
QUERY_STRING - זהו הטקסט בסיום ה- URL אשר כולל ?, למשל:
http://somedomain.com/directory/file.html?querystringtext
נעשה זאת בצורה הבאה:
|
<!--#echo var="QUERY_STRING" -->
|
|
להלן דוגמא לשימוש בפקודה הנ"ל:
נוסיף קישור ל- color.html בדף אחד, בעזרת התחביר להלן:
|
<a href="color.html?red">color</A>
|
|
כעת ניצור color.html ונוסיף לתוכו את התוספת הבאה.
הפקודה נכנסת לדף המקושר ולא לדף בו מופיע הקישור, בצורה הבאה:
|
<!--#set var="color" value="$QUERY_STRING" -->
<font size="+2" face="Arial,Helvetica" color=
"<!--#echo var="color" -->">
<!--#echo var="QUERY_STRING" --></font>
|
|
לחץ כאן ע"מ לראות את הדוגמא.
אם נלך ישירות ל- color.html מבלי ללחוץ על הקישור, לא נראה דבר. במקרה הזה, תוכן הדף הוא מלה אחת - המחרוזת שאחרי ? ב- URL.
אם ה- URL היה <"A HREF="color.utml?green>, היינו רואים את המלה green במקום red.
REMOTE_HOST - שם ה - host של הלקוח, מגיש הבקשה.
|
<--#echo var="REMOTE_HOST" -->
|
|
REMOTE_ADDR - כתובת ה - IP של הלקוח, מגיש הבקשה.
|
<!--#echo var="REMOTE_ADDR" -->
|
|
AUTH_TYPE - שיטת האימות בה משתמשים כדי לאמת משתמש.
|
<!--#echo var="AUTH_TYPE" -->
|
|
REMOTE_USER - אם העמוד מוגן, זהו השם המאומת של המשתמש.
|
<!--#echo var="REMOTE_USER" -->
|
|
REMOTE_IDENT - בשרתים שתומכים בזיהוי RFC 931, משתנה זה מחזיר את שם הלקוח שמוחזר מהשרת.
יש להגביל את השימוש במשתנה זה לתיעוד בלבד.
|
<!--#echo var="REMOTE_IDENT" -->
|
|
CONTENT_TYPE - זהו סוג התוכן של הנתונים לשאילתות, בעלות מידע מצורף כגון PUT או HTTP POST .
|
<!--#echo var="CONTENT_TYPE" -->
|
|
CONTENT_LENGTH - אורך המידע המצורף הניתן ע"י הלקוח.
|
<!--#echo var="CONTENT_LENGTH" -->
|
|
HTTP_ACCEPT - רשימה של סוגי MIME שהלקוח יקבל. הפריטים ברשימה יופרדו באמצעות פסיקים.
|
<!--#echo var="HTTP_ACCEPT" -->
|
|
HTTP_USER_AGENT - תוכנת הדפדפן בה משתמש הלקוח. מה שמוחזר מופיע בפורמט של תוכנה/ספריית הגרסה/גרסה
לדוגמא:
Apache/1.2.6 FrontPage/3.0.4
|
<!--#echo var="HTTP_USER_AGENT" -->
|
|
HTTP_REFERER - ה- URL של המסמך שמכיל את הקישור לדף.
|
<!--#echo var="HTTP_REFERER" -->
|
|
fsize - מדפיס את התאריך האחרון בו עודכן הקובץ . ניתן להגדיר את הפורמט בו מוצג התאריך ע"י שימוש ב - fsize יחד עם הפרמטר config sizefmt.
fsize דומה לפקודת ה-include, בכך שהוא מקבל הן קובץ והן פרמטר וירטואלי (הכוונה בביטוי וירטואלי הוא שניתן להדפיס את התאריך של קובץ שנמצא בכל מקום בשרת, לא רק את התאריך של הקובץ עליו עובדים באותו זמן).
|
<!--#fsize file="index_working.html" -->
|
|
flastmod - מדפיס את התאריך האחרון בו עודכן קובץ מסוים. ניתן להגדיר את הפורמט בו מוצג התאריך ע"י שימוש ב - flastmod יחד עם הפרמטר config timefmt.
flastmod דומה לפקודת ה-include בכך שהוא מקבל הן קובץ והן פרמטר וירטואלי.
|
<!--#config timefmt="%A, the %d of %B, in the year %Y" -->
<!--#flastmod file="file.html" -->
|
|
להלן טריק להצגת כל תאריכי העדכון האחרונים על כל הקישורים באינדקס: יש להוסיף את השורה הבאה יחד עם הנתיב הנכון אחרי כל קישור:
|
<!--#config timefmt=" %B %d, %Y" -->
<A HREF="/directory/file.html">File</A>
<!--#flastmod virtual="/directory/file.html" -->
<A HREF="/another_directory/another_file.html">Another File</A>
<!--#flastmod virtual="/another_directory/another_file.html" -->
|
|
הפלט המוצג:
|
File April 19, 2000
Another File January 08, 2000
|
|
זה נראה כמו הרבה עבודה לשני קישורים קטנים אך אם נכפיל זאת ב- 20 כפול תדירות השינויים - נווכח בתועלת של flastmod בעדכון תאריכים בעמוד אינדקס זה.
exec - פקודה זו מבצעת פקודת Shell או CGI script. חייבים להפעיל אותה לפני שניתן להשתמש בה. תגים תקפים הם:
cmd - מבצע את המחרוזת הנתונה בעזרת /bin/sh. האופציה IncludesNOEXEC מבטלת פקודה זו.
cgi - מבצע cgi script. הפקודה הבאה (בדוגמא להלן) תמקם מונה בעמוד, בתנאי
שה - counter.pl script נמצא ב - cgi-bin בשרת.
לדוגמא:
|
<!--#exec cgi="/cgi-bin/counter.pl" -->
|
|
|
|