?

Log in

Сб, 3 дек, 2011, 18:10
WSH (Windows Script Host) как CGI

Реализуем серверный JavaScript на базе WSH (Windows Script Host)



Чтобы не нагружать систему сторонними интерпретаторами, можно осуществить поддержку штатного WSH (JScript, VBScript и др.) в сценариях CGI. Если в роли веб-сервера использовать обычный Apache HTTP Server, то на нем в CGI без проблем будут работать консольные приложения (exe) и даже командные файлы (bat/cmd), однако WSH (wsf/js/vbs) потребует небольшой доработки. Поиск не дает прямых решений: первое предлагает заменить "#" на знак комментария "'" в первой строке указывающей путь к интерпретатору и использовать только vbs и wsf-Файлы, второе - запускать один скрипт из другого косвенным образом. Оба метода имеют ряд недостатков, потому опишу как напрямую (без костылей) запускать WSH через CGI.

Прежде чем начать, рекомендую ознакомиться с особенностями написания скриптов на справочной странице WSH. Имейте ввиду что WSH имеет уникальную объектную модель и может понадобиться внести значительные изменения при переносе сайта на другой движок.

Для начала создадим простейший скрипт на JS из одной строчки для теста и поместим его в cgi-bin:

test.js :

WScript.Echo("Content-Type: text/plain\n\nHello world!");


По умолчанию WSH запускается в графическом режиме, необходимо переключить его в консольный (текстовый) режим, для этого откроем командную строку и введем:

CScript //H:CScript


Если все сделано правильно, то мы получим подтверждение (The default script host is now set to "cscript.exe".), с этого момента WSH по умолчанию будет запускаться в консольном (текстовом) режиме, хотя это и не единственный способ переобозначить интерпретатор.

Если теперь попытаться открыть http://localhost/cgi-bin/test.js то мы получим ошибку "500 Internal Server Error", а error.log будет содержать следующую запись:

[...]/cgi-bin/test.js is not executable; ensure interpreted scripts have "#!" first line


Это означает что сервер не знает как запускать наш скрипт и просит указать интерпретатор в первой строке (shebang) и если же добавить строку "#!C:\WINDOWS\system32\cscript.exe" то уже интерпретатор выдаст ошибку при попытке запустить скрипт:

[...]\test.js(1, 1) Microsoft JScript compilation error: Invalid character


Вместо того чтобы добавлять такую строку, просто отключим трактовку первой строки как пути к интерпретатору вообще. Для этого в httpd.conf добавим (или раскомментируем если есть) директиву:

ScriptInterpreterSource Registry


Теперь при попытке зайти на страничку со скриптом, сервер выполнит действие по умолчанию для данного типа (расширения) файлов, указанное в системном реестре. Запись в error.log примет вид:

[...] malformed header from script. Bad header=Microsoft (R) Windows Script H: test.js


Логотип WSH воспринимается как некорректный HTTP-заголовок, отключить отображение логотипа можно через редактор реестра (regedit.exe):

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Script Host\Settings]
"DisplayLogo"="0"


В итоге, на странице с нашим тестовым скриптом мы увидим долгожданный "Hello world!". Отныне все скрипты WSH не отличаются от любых других CGI сценариев и для них справедливо все тоже самое. Единственное замечание, если запускать CGI сценарии не в cgi-bin, а по расширению/типу файлов (ExecCGI), то учитывайте что клиентский и серверный JavaScript могут иметь одинаковое расширение/тип файла (*.js), но один должен передаваться клиенту, а другой исполняться на сервере, и нужно их разделять.