среда, 5 сентября 2018 г.
Stacktrace function - Custom stack trace in JavaScript
function stacktrace () {
var stacktraceData = getStacktraceData(arguments.callee.caller);
function getStacktraceData (functionThatCalledThisStacktraceFunction) {
if (functionThatCalledThisStacktraceFunction) {
return (
getStacktraceData(functionThatCalledThisStacktraceFunction.caller)
+ functionThatCalledThisStacktraceFunction.toString().split('(')[0].substring(9) // Function name
+ '('
+ Array.prototype.slice.call(functionThatCalledThisStacktraceFunction.arguments).join(', ') // Function arguments
+ ')'
+ '\n'
);
} else {
return '';
}
}
return stacktraceData;
}
main();
function main () {
var x = execute();
var y = add(2, 3);
}
function execute () {
calc();
}
function calc () {
return add(8, 11) + add(9, 14);
}
function add (x, y) {
console.log(stacktrace());
return x + y;
}
среда, 6 июня 2018 г.
NPM Cheat Sheet
# NPM CheatSheet.
# NPM поставляется вместе с Node.js.
# Инструкция по созданию своего npm package: https://www.npmjs.org/doc/misc/npm-developers.html
# Больше информации на: https://www.npmjs.org/doc/
# 1. NPM Команды для командного терминала.
# Локальный режим включен по умолчанию.
# Используйте --global или -g для выполнения команды в глобальном режиме.
npm <cmd> -h # быстрая подсказка по команде <cmd>
npm -l # вывести список всех команд NPM с их описанием
npm adduser # добавить нового пользователя реестра
npm bin # показать местонахождение папки .bin
npm bugs <pkgname> # загрузить в браузере страницу с описанием багов указанной библиотеки
npm build <package-folder> # собрать библиотеку (не должно вызываться напрямую)
npm cache [add|ls|clean] <tarball|folder> # работа с кэшем установленных библиотек
npm config [set|get|delete|list|edit] <key> <value> #управление конфигурационным файлом
npm dedupe [package names...] --tag # уменьшить дублирование установленных библиотек
npm depcrecate <name>[@<version>] <message> # пометить версию библиотеки, как устаревшую (для этого вы должны быть владельцем данной библиотеки)
npm docs [<pkg-name> [<pkg-name> ...]] # открыть страницу с документацией по библиотеке в браузере
npm edit <name>[@<version>] # отредактировать установленную библиотеку (по умолчанию будет использован редактор "vi")
npm explore <name>[@<version>] [ -- <cmd>] # просмотреть установленную библиотеку
npm faq # список часто задаваемых вопросов об NPM (аналог help)
npm help-search <some search terms> # поиск по документации NPM
npm help <topic> <some search terms> # вывести подсказку по NPM
npm init # создать файл package.json
npm install <folder|name@<tag|version>|tarball> # установить библиотеку из репозитория NPM (необязательные флаги: --save, --save-dev, --save-optional, --save-exact)
npm link <pkgname> # симлинк на папку библиотеки
npm ls <pkg> # вывести список всех установленных библиотек (и их зависимостей)
npm outdated [<name> [<name> ...]] # проверить какие библиотеки уже устарели
npm owner [ls|add|rm] <pkg-name> <user> # управление владельцами библиотек
npm pack [<pkg> [<pkg> ...]] # создать архив tarball из библиотеки
npm prefix # отобразить префикс
npm prune [<name> [<name ...]] --production # удалить установленные посторонний библиотеки, не перечисленные в файле package.json
npm publish <tarball|folder> [--tag <tag>] # опубликовать библиотеку в хранилище NPM
npm rebuild [<name > [<name> ...]] # пересобрать библиотеку
npm repo <pkgname> # открыть репозиторий библиотеки в браузере
npm restart <name> # запустить библиотеку
npm rm <name> # удалить установленную библиотеку
npm root # отобразить путь до папки node_modules
npm run [<pkg>] [command] # запустить команду, описанную в разделе script файла package.json
npm search [search terms ...] [--long] # найти библиотеку с таким-то названием в репозитории NPM
npm shrinkwrap # создать файл npm-shrinkwrap.json, в котором перечислены и зафиксированы все установленные библиотеки и их версии. Если это файл присутствует, то инсталляция библиотек будет происходить строго с учетом данных из этого фала.
npm star <pkgname> [<pkg>, ...] # пометить любимые библиотеки
npm stars [username] # посмотреть библиотеки отмеченные, как любимые
npm start <name> # выполнить команду start библиотеки
npm stop <name> # выполнить команду stop библиотеки
npm submodule <pkg> # добавить библиотеку в качестве git submodule
npm tag <name>@<version> # пометить tag публичную версию библиотеки
npm test <name> # выполнить команду test библиотеки
npm unpublish <name>[@<version>] # удалить библиотеку из репозитория NPM
npm unstar <pkgname> [<pkg>, ...] # удалить пометку библиотеки, как любимую
npm update [-g] [<name> [<name> ...]] # обновить установленную версию библиотеки
npm version [<newversion> | major | minor | patch] # поднять версию библиотеки
npm view <name>[@<version>] [<field<[.<subfield>] ...] # показать информацию о библиотеке
npm whoami # показать информацию о текущем пользователе
// 2. NPM API документация.
// Перед использованием команд NPM должна быть вызвана функция npm.load().
npm.load(configs, callback); // загрузить настройки из кофигурационного файла
npm.commands.bin(args, callback); // показать местонахождения папки npm bin
npm.commands.bugs(package, callback); // открыть в браузере информацию о багах данной библиотеки
npm.commands.cache([args], callback); // программное управление npm cache
npm.commands.cache.clean([args], callback); // очистка npm cache
npm.commands.cache.add([args], callback); // добавление npm cache
npm.commands.cache.read(name, version, forceBypass, callback); // чтение npm cache
npm.commands[<command>](args, callback); // выполнить команду NPM
npm.commands.config(args, callback); // управление конфигурационным файлом NPM
npm.config.get(key); // получить установленное значение конфига по ключу
npm.config.set(key, value); // установить значение конфига по ключу
npm.commands.deprecate(args, callback); // пометить версию библиотеки, как устаревшую
npm.commands.docs(package, callback); // открыть страницу с документацией библиотеки в браузере
npm.commands.edit(package, callback); // отредактировать установленную библиотеку
npm.commands.explore(args, callback); // просмотреть библиотеку
npm.commands.helpSearch(args, [silent,] callback); // поиск по подсказкам в документации NPM
npm.commands.init(args, callback); // создать файл package.json
npm.commands.install([where,] packages, callback); // установить библиотеку
npm.commands.link([packages,] callback); // создать симлинк на папку библиотеки
npm.commands.ls(args, [silent,] callback); // показать список всех установленных библиотек
npm.commands.outdated([packages,] callback); // проверить не устарели ли библиотеки
npm.commands.owner(args, callback); // управление владельцами библиотек
npm.commands.pack([packages,] callback); // создать архив tarball из папки билиотеки
npm.commands.prefix(args, callback); // показать префикс
npm.commands.prune([packages,] callback); // удалить установленные посторонний библиотеки, не перечисленные в файле package.json
npm.commands.publish([packages,] callback); // опубликовать библиотеку в репозиторий NPM
npm.commands.rebuild([packages,] callback); // пересобрать библиотеку
npm.commands.repo(package, callback); // открыть страницу с репозиторием библиотеки в браузере
npm.commands.restart(packages, callback); // выполнить команду start библиотеки
npm.commands.root(args, callback); // отобразить путь до папки node_modules
npm.commands.run-script(args, callback); // выполнить команду из разделе script файла package.json
npm.commands.search(searchTerms, [silent,] [staleness,] callback); // найти библиотеку в репозитории NPM
npm.commands.shrinkwrap(args, [silent,] callback); // создать файл npm-shrinkwrap.json, в котором перечислены и зафиксированы все установленные библиотеки и их версии. Если это файл присутствует, то инсталляция библиотек будет происходить строго с учетом данных из этого фала.
npm.commands.start(packages, callback); // выполнить команду start библиотеки
npm.commands.stop(packages, callback); // выполнить команду stop библиотеки
npm.commands.submodule(packages, callback); // добавить библиотеку в качестве git submodule
npm.commands.tag(package@version, tag, callback); // пометить tag публичную версию библиотеки
npm.commands.test(packages, callback); // выполнить команду test библиотеки
npm.commands.uninstall(packages, callback); // удалить установленную библиотеку
npm.commands.unpublish(package, callback); // удалить библиотеку из репозитория NPM
npm.commands.update(packages, callback); // обновить установленную версию библиотеки
npm.commands.version(newversion, callback); // поднять версию библиотеки
npm.commands.view(args, [silent,] callback); // показать информацию о библиотеке
npm.commands.whoami(args, callback); // показать информацию о текущем пользователе
// 3. Содержимое файла package.json
{
"name": "module-name",
"version": "10.5.2",
"description": "An example module to illustrate the usage of a package.json",
"keywords": ["nodejitsu", "example", "browsenpm"],
"license": "MIT",
"author": "Your Name <you.name@example.org>",
"contributors": [{
"name": "Foo Bar",
"email": "foo.bar@example.com"
}],
"publishConfig": {
"registry": "https://your-private-hosted-npm.registry.nodejitsu.com"
},
"repository": {
"type": "git",
"url": "https://github.com/nodejitsu/browsenpm.org"
},
"bugs": {
"url": "https://github.com/nodejitsu/browsenpm.org/issues"
},
"preferGlobal": true,
"private": true,
"analyze": true,
"subdomain": "foobar",
"bin": {
"module-name": "./bin/module-name"
},
"main": "lib/foo.js",
"script": {
"test": "vows --spec --isolate",
"start": "node index.js",
"predeploy": "echo i am about to deploy",
"postdeploy": "echo i have deployed",
"prepublish": "coffee --bare --compile --output lib/foo src/foo/*.coffee"
},
"dependencies": {
"primus": "*",
"async": "~0.8.0",
"express": "4.2.x",
"winston": "git://github.com/flatiron/winston#master",
"bigpipe": "bigpipe/pagelet",
"plates": "https://github.com/flatiron/plates/tarball/master"
},
"devDependencies": {
"vows": "^0.7.0",
"assume": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
"pre-commit": "*"
}
}
# NPM поставляется вместе с Node.js.
# Инструкция по созданию своего npm package: https://www.npmjs.org/doc/misc/npm-developers.html
# Больше информации на: https://www.npmjs.org/doc/
# 1. NPM Команды для командного терминала.
# Локальный режим включен по умолчанию.
# Используйте --global или -g для выполнения команды в глобальном режиме.
npm <cmd> -h # быстрая подсказка по команде <cmd>
npm -l # вывести список всех команд NPM с их описанием
npm adduser # добавить нового пользователя реестра
npm bin # показать местонахождение папки .bin
npm bugs <pkgname> # загрузить в браузере страницу с описанием багов указанной библиотеки
npm build <package-folder> # собрать библиотеку (не должно вызываться напрямую)
npm cache [add|ls|clean] <tarball|folder> # работа с кэшем установленных библиотек
npm config [set|get|delete|list|edit] <key> <value> #управление конфигурационным файлом
npm dedupe [package names...] --tag # уменьшить дублирование установленных библиотек
npm depcrecate <name>[@<version>] <message> # пометить версию библиотеки, как устаревшую (для этого вы должны быть владельцем данной библиотеки)
npm docs [<pkg-name> [<pkg-name> ...]] # открыть страницу с документацией по библиотеке в браузере
npm edit <name>[@<version>] # отредактировать установленную библиотеку (по умолчанию будет использован редактор "vi")
npm explore <name>[@<version>] [ -- <cmd>] # просмотреть установленную библиотеку
npm faq # список часто задаваемых вопросов об NPM (аналог help)
npm help-search <some search terms> # поиск по документации NPM
npm help <topic> <some search terms> # вывести подсказку по NPM
npm init # создать файл package.json
npm install <folder|name@<tag|version>|tarball> # установить библиотеку из репозитория NPM (необязательные флаги: --save, --save-dev, --save-optional, --save-exact)
npm link <pkgname> # симлинк на папку библиотеки
npm ls <pkg> # вывести список всех установленных библиотек (и их зависимостей)
npm outdated [<name> [<name> ...]] # проверить какие библиотеки уже устарели
npm owner [ls|add|rm] <pkg-name> <user> # управление владельцами библиотек
npm pack [<pkg> [<pkg> ...]] # создать архив tarball из библиотеки
npm prefix # отобразить префикс
npm prune [<name> [<name ...]] --production # удалить установленные посторонний библиотеки, не перечисленные в файле package.json
npm publish <tarball|folder> [--tag <tag>] # опубликовать библиотеку в хранилище NPM
npm rebuild [<name > [<name> ...]] # пересобрать библиотеку
npm repo <pkgname> # открыть репозиторий библиотеки в браузере
npm restart <name> # запустить библиотеку
npm rm <name> # удалить установленную библиотеку
npm root # отобразить путь до папки node_modules
npm run [<pkg>] [command] # запустить команду, описанную в разделе script файла package.json
npm search [search terms ...] [--long] # найти библиотеку с таким-то названием в репозитории NPM
npm shrinkwrap # создать файл npm-shrinkwrap.json, в котором перечислены и зафиксированы все установленные библиотеки и их версии. Если это файл присутствует, то инсталляция библиотек будет происходить строго с учетом данных из этого фала.
npm star <pkgname> [<pkg>, ...] # пометить любимые библиотеки
npm stars [username] # посмотреть библиотеки отмеченные, как любимые
npm start <name> # выполнить команду start библиотеки
npm stop <name> # выполнить команду stop библиотеки
npm submodule <pkg> # добавить библиотеку в качестве git submodule
npm tag <name>@<version> # пометить tag публичную версию библиотеки
npm test <name> # выполнить команду test библиотеки
npm unpublish <name>[@<version>] # удалить библиотеку из репозитория NPM
npm unstar <pkgname> [<pkg>, ...] # удалить пометку библиотеки, как любимую
npm update [-g] [<name> [<name> ...]] # обновить установленную версию библиотеки
npm version [<newversion> | major | minor | patch] # поднять версию библиотеки
npm view <name>[@<version>] [<field<[.<subfield>] ...] # показать информацию о библиотеке
npm whoami # показать информацию о текущем пользователе
// 2. NPM API документация.
// Перед использованием команд NPM должна быть вызвана функция npm.load().
npm.load(configs, callback); // загрузить настройки из кофигурационного файла
npm.commands.bin(args, callback); // показать местонахождения папки npm bin
npm.commands.bugs(package, callback); // открыть в браузере информацию о багах данной библиотеки
npm.commands.cache([args], callback); // программное управление npm cache
npm.commands.cache.clean([args], callback); // очистка npm cache
npm.commands.cache.add([args], callback); // добавление npm cache
npm.commands.cache.read(name, version, forceBypass, callback); // чтение npm cache
npm.commands[<command>](args, callback); // выполнить команду NPM
npm.commands.config(args, callback); // управление конфигурационным файлом NPM
npm.config.get(key); // получить установленное значение конфига по ключу
npm.config.set(key, value); // установить значение конфига по ключу
npm.commands.deprecate(args, callback); // пометить версию библиотеки, как устаревшую
npm.commands.docs(package, callback); // открыть страницу с документацией библиотеки в браузере
npm.commands.edit(package, callback); // отредактировать установленную библиотеку
npm.commands.explore(args, callback); // просмотреть библиотеку
npm.commands.helpSearch(args, [silent,] callback); // поиск по подсказкам в документации NPM
npm.commands.init(args, callback); // создать файл package.json
npm.commands.install([where,] packages, callback); // установить библиотеку
npm.commands.link([packages,] callback); // создать симлинк на папку библиотеки
npm.commands.ls(args, [silent,] callback); // показать список всех установленных библиотек
npm.commands.outdated([packages,] callback); // проверить не устарели ли библиотеки
npm.commands.owner(args, callback); // управление владельцами библиотек
npm.commands.pack([packages,] callback); // создать архив tarball из папки билиотеки
npm.commands.prefix(args, callback); // показать префикс
npm.commands.prune([packages,] callback); // удалить установленные посторонний библиотеки, не перечисленные в файле package.json
npm.commands.publish([packages,] callback); // опубликовать библиотеку в репозиторий NPM
npm.commands.rebuild([packages,] callback); // пересобрать библиотеку
npm.commands.repo(package, callback); // открыть страницу с репозиторием библиотеки в браузере
npm.commands.restart(packages, callback); // выполнить команду start библиотеки
npm.commands.root(args, callback); // отобразить путь до папки node_modules
npm.commands.run-script(args, callback); // выполнить команду из разделе script файла package.json
npm.commands.search(searchTerms, [silent,] [staleness,] callback); // найти библиотеку в репозитории NPM
npm.commands.shrinkwrap(args, [silent,] callback); // создать файл npm-shrinkwrap.json, в котором перечислены и зафиксированы все установленные библиотеки и их версии. Если это файл присутствует, то инсталляция библиотек будет происходить строго с учетом данных из этого фала.
npm.commands.start(packages, callback); // выполнить команду start библиотеки
npm.commands.stop(packages, callback); // выполнить команду stop библиотеки
npm.commands.submodule(packages, callback); // добавить библиотеку в качестве git submodule
npm.commands.tag(package@version, tag, callback); // пометить tag публичную версию библиотеки
npm.commands.test(packages, callback); // выполнить команду test библиотеки
npm.commands.uninstall(packages, callback); // удалить установленную библиотеку
npm.commands.unpublish(package, callback); // удалить библиотеку из репозитория NPM
npm.commands.update(packages, callback); // обновить установленную версию библиотеки
npm.commands.version(newversion, callback); // поднять версию библиотеки
npm.commands.view(args, [silent,] callback); // показать информацию о библиотеке
npm.commands.whoami(args, callback); // показать информацию о текущем пользователе
// 3. Содержимое файла package.json
{
"name": "module-name",
"version": "10.5.2",
"description": "An example module to illustrate the usage of a package.json",
"keywords": ["nodejitsu", "example", "browsenpm"],
"license": "MIT",
"author": "Your Name <you.name@example.org>",
"contributors": [{
"name": "Foo Bar",
"email": "foo.bar@example.com"
}],
"publishConfig": {
"registry": "https://your-private-hosted-npm.registry.nodejitsu.com"
},
"repository": {
"type": "git",
"url": "https://github.com/nodejitsu/browsenpm.org"
},
"bugs": {
"url": "https://github.com/nodejitsu/browsenpm.org/issues"
},
"preferGlobal": true,
"private": true,
"analyze": true,
"subdomain": "foobar",
"bin": {
"module-name": "./bin/module-name"
},
"main": "lib/foo.js",
"script": {
"test": "vows --spec --isolate",
"start": "node index.js",
"predeploy": "echo i am about to deploy",
"postdeploy": "echo i have deployed",
"prepublish": "coffee --bare --compile --output lib/foo src/foo/*.coffee"
},
"dependencies": {
"primus": "*",
"async": "~0.8.0",
"express": "4.2.x",
"winston": "git://github.com/flatiron/winston#master",
"bigpipe": "bigpipe/pagelet",
"plates": "https://github.com/flatiron/plates/tarball/master"
},
"devDependencies": {
"vows": "^0.7.0",
"assume": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
"pre-commit": "*"
}
}
Node.js Quick CheatSheet
/* *******************************************************************************************
* Краткий обзор
* http://nodejs.org/api/synopsis.html
* ******************************************************************************************* */
var http = require('http');
// Пример сервера, оправляющего в браузер ответ 'Hello World'.
// Для запуска сервера поместите код в файл с именем example.js и выполните его с помощью Node.js.
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World');
}).listen(8000);
console.log('Сервер запущен по адресу http://127.0.0.1:8000/');
/* *******************************************************************************************
* Глобальные объекты
* http://nodejs.org/api/globals.html
* ******************************************************************************************* */
__filename; // Абсолютный путь до файла, код которого выполняется.
__dirname; // Абсолютный путь до директории, в которой находится файл с выполняемым кодом.
module; // Ссылка на текущий модуль. В частности module.exports используется для определения того, что модуль экспортирует и делает доступным для загрузки через require().
exports; // Укороченная ссылка на module.exports.
process; // Глобальный объект текущего запущенного процесса Node.js. Доступен везде. Является экземпляром класса EventEmitter.
Buffer; // Глобальный класс для работы напрямую с двоичными данными.
/* *******************************************************************************************
* Консоль
* http://nodejs.org/api/console.html
* ******************************************************************************************* */
console.log([data], [...]); // Печатает текст вместе с символом перевода на новую строку на конце в stdout командного терминала.
console.info([data], [...]); // Тоже самое, что и console.log.
console.error([data], [...]); // Тоже самое, что и console.log, но печатает текст в stderr командного терминала.
console.warn([data], [...]); // Тоже самое, что и console.error.
console.dir(obj); // Использует util.inspect на obj и печатает итоговую строку с текстом в stdout командного терминала.
console.time(label); // Запускает замер времени.
console.timeEnd(label); // Останавливает замер времени и выводит итоговое время в stdout командного терминала.
console.trace(label); // Печатает содержимое стека (stack trace) в данный момент в stderr командного терминала.
console.assert(expression, [message]); // Тоже самое, что и assert.ok(), в котором, если выполняемое выражение получает в итоге значение false, то выбрасывается исключение AssertionError с соответствующим сообщением.
/* *******************************************************************************************
* Таймеры
* http://nodejs.org/api/timers.html
* ******************************************************************************************* */
setTimeout(callback, delay, [arg], [...]); // Выполняет функцию callback один раз через указанное число миллисекунд. В функцию callback также можно передать указанные аргументы.
clearTimeout(t); // Отменяет выполнение ранее созданного таймера с помощью функции setTimeout().
setInterval(callback, delay, [arg], [...]); // Повторно выполняет функцию callback через заданное число миллисекунд до тех пор, пока не будет отменено с помощью функции clearInterval(). В функцию callback также можно передать указанные аргументы.
clearInterval(t); // Отменяет выполнение ранее созданного таймера с помощью функции setInterval().
setImmediate(callback, [arg], [...]); // Немедленно выполняет функцию callback после выполнения всех операций ввода-вывода и до setTimeout и setInterval.
clearImmediate(immediateObject); // Отменяет выполнение ранее созданного таймера с помощью функции setImmediate().
unref(); // Позволяет создавать таймер, который будет активен только до того момента, пока программа Node.js выполняется и есть активные элементы в цикле event loop. После завершения всех операций в цикле event loop программа будет закрыта.
ref(); // Если вы ранее выполнили функцию unref() для таймера, то вы можете выполнить функцию ref(), которая позволит таймеру удерживать вашу программу от закрытия после того, как все операции в цикле event loop будут завершены.
/* *******************************************************************************************
* Модули
* http://nodejs.org/api/modules.html
* ******************************************************************************************* */
var module = require('./file.js'); // Загружает модуль file.js, находящийся в той же директории.
module.require('./another_file.js'); // Загружает модуль another_file.js так, как если бы функция require() была вызвана самим модулем.
module.id; // Идентификатор модуля. Обычно это путь до файла.
module.filename; // Абсолютный путь до файла с его именем.
module.loaded; // Загружен ли уже модуль или он всё ещё загружается.
module.parent; // Родительский модуль, который загрузил данный модуль.
module.children; // Дочерние модули, которые загрузил данный модуль через функцию require().
// Экспорт из модуля функции с именем area.
exports.area = function (r) {
return Math.PI * r * r;
};
// module.exports - это объект с перечнем экспортируемых из данного модуля элементов.
// Если вы хотите, то можете превратить его в функцию, например функцию-конструктор, которая будет создавать экспортируемые объекты или вы можете присвоить ему экспортируемый объект, в котором находятся все экспортируемые элементы сразу.
// Присвоение значения module.exports затирает значения в exports.
module.exports = function(width) {
return {
area: function() {
return width * width;
}
};
}
/* *******************************************************************************************
* Процесс
* http://nodejs.org/api/process.html
* ******************************************************************************************* */
process.on('exit', function(code) {}); // Функция вызывается, когда процесс Node.js завершается и происходит выход из программы.
process.on('uncaughtException', function(err) {}); // Функция вызывается, когда появляется никем не перехваченное исключение. В этом случае программа не вылетает и продолжает работать выполняться со сбоем, поэтому не стоит эту функцию использовать.
process.stdout; // Поток для записи в stdout командного терминала.
process.stderr; // Поток для записи в stderr командного терминала.
process.stdin; // Поток чтения из stdin командного терминала.
process.argv; // Массив, содержащий все аргументы, переданные из командной строки терминала во время запуска программы.
process.env; // Объект, содержащий значения переменных среды окружения (например значение переменной среды Path из Windows).
process.execPath; // Абсолютный путь до файла node.exe, который запустил данную JavaSctipt-программу.
process.execArgv; // Массив, содержащий все аргументы командных опций Node.js, которые были введены при запуске программы.
process.arch; // Архитектура процессора системы: 'arm', 'ia32', 'x64'.
process.config; // Объект, содержащий в себе конфигурационные опции, которые были использованы для компиляции и создания текущего файла node.exe.
process.pid; // Идентификатор текущего запущенного процесса PID .
process.platform; // Операционная система, в которой запущена данная программа: 'darwin', 'freebsd', 'linux', 'sunos', 'win32'.
process.title; // Getter/setter для установки имени процесса для отображения в 'ps'. (Например C:\\WINDOWS\\system32\\cmd.exe - node)
process.version; // Версия Node.js.
process.versions; // Версия Node.js и некоторых его внутренних модулей.
process.abort(); // Прервать выполнение программы. Это заставит Node.js выйти из программы и сгенерировать core file.
process.chdir(dir); // Изменить текущую рабочую директорию, из которой была запущена программа. Выбрасывает исключение, если изменить текущую рабочую директорию невозможно.
process.cwd(); // Текущая рабочая директория, из которой была запущена программа.
process.exit([code]); // Завершить программу с заданным кодом. Если код не задан, то программ успешно завершится с кодом 0.
process.getgid(); // Получить идентификатор группы пользователей данного процесса.
process.setgid(id); // Установить идентификатор группы пользователей данного процесса.
process.getuid(); // Получить идентификатор пользователя данного процесса.
process.setuid(id); // Установить идентификатор пользователя данного процесса.
process.getgroups(); // Получить массив с идентификаторами дополнительных групп пользователей.
process.setgroups(grps); // Установить идентификаторы дополнительных групп пользователей.
process.initgroups(user, extra_grp); // Читает содержимое /etc/group и инициализирует лист доступа для группы, использую группы, к которых данный пользователь является их членом.
process.kill(pid, [signal]); // Посылает сигнал signal процессу с идентификатором pid.
process.memoryUsage(); // Возвращает объект, описывающий использование памяти данным процессом Node.js в байтах.
process.nextTick(callback); // Вызвать функцию callback на следующем шаге цикла event loop.
process.maxTickDepth; // Обратные вызовы, переданные процессу .nextTick обычно вызывается в конце текущего потока выполнения и, таким образом, примерно так же быстро, как вызов функции синхронно.
process.umask([mask]); // Устанавливает или считывает маску создания процесса файла.
process.uptime(); // Время выполнения данной программы в секундах.
process.hrtime(); // Текущее время в высоком разрешении в формате массива [seconds, nanoseconds] (удобно для точного замера времени выполнения какой-либо функции).
/* *******************************************************************************************
* Дочерний процесс
* http://nodejs.org/api/child_process.html
* ******************************************************************************************* */
// Дочерний процесс - это отдельная Node.js программа, запускаемая из родительской Node.js программы.
ChildProcess; // Класс. ChildProcess является EventEmitter.
child.stdin; // Поток ввода дочернего процесса stdin.
child.stdout; // Поток вывода дочернего процесса stdout.
child.stderr; // Поток вывода ошибок дочернего процесса stderr.
child.pid; // Идентификатор дочернего процесса PID.
child.connected; // Если .connected равно false, то больше невозможно посылать сообщения в дочерний процесс из родительского процесса.
child.kill([signal]); // Послать сигнал signal в дочерний процесс.
child.send(message, [sendHandle]); // После создания дочернего процесса с помощью функции child_process.fork() вы можете отправлять в дочерний процесс данные с помощью функции child.send(message, [sendHandle]) и получать их в дочернем процессе с помощью события .on('message', callback).
child.disconnect(); // Закрыть канал передачи данных IPC между родительским и дочерним процессом. channel between parent and child, что позволяет дочернему процессу завершить своё выполнение, поскольку больше никаких соединений с ним не установлено.
child_process.spawn(command, [args], [options]); // Запускает дочерний процесс с переданными в него аргументами. Передача данных в дочерний процесс или из него осуществляется через потоки streams.
child_process.exec(command, [options], callback); // Выполняет команду в командном терминале и возвращает результат её выполнения.
child_process.execFile(file, [args], [options], [callback]); // Выполняет файл в командном терминале и возвращает результат его выполнения.
child_process.fork(modulePath, [args], [options]); // Особая форма функции spawn(), которая выполняет JavaScript-файл, как отдельную Node.js программу. Общение между родительской и дочерней программой производится через посылку друг другу сообщений messafe.
/* *******************************************************************************************
* Утилиты
* http://nodejs.org/api/util.html
* ******************************************************************************************* */
// Эти функции содержатся в модуле 'util'. Используйте require('util') для получения доступа к ним.
util.format(format, [...]); // Возвращает отформатированную строку. Символы для подстановки строкиЮ числа и данных в формате JSON: %s, %d, %j
util.debug(string); // Функция для синхронного вывода текста в stderr командного терминала.
util.error([...]); // Тоже самое. что и util.debug(), но только выводит все аргументы stderr командного терминала.
util.puts([...]); // Функция для синхронного вывода текста в stdout командного терминала с символом новой строки после каждого аргумента.
util.print([...]); // Функция для синхронного вывода текста в stdout командного терминала без символов новой строки после каждого аргумента.
util.log(string); // Выводит текст вместе с временной меткой в stdout командного терминала.
util.inspect(object, [opts]); // Выводит объект в виде строки, что удобно для поиска багов. (Опции: showHidden, depth, colors, customInspect)
util.isArray(object); // Возвращает true, если переданный объект является массивом и false, если нет.
util.isRegExp(object); // Возвращает true, если переданный объект является регулярным выражением и false, если нет.
util.isDate(object); // Возвращает true, если переданный объект является датой и false, если нет.
util.isError(object); // Возвращает true, если переданный объект является объектом Error и false, если нет.
util.promisify(fn); // Берет функцию, в которой последний аргумент является callback-функцией и превращает её в функцию, возвращающую promise.
util.inherits(constructor, superConstructor); // Копирует методы прототипа из одной функции конструктора в другую функцию конструктор.
/* *******************************************************************************************
* События
* http://nodejs.org/api/events.html
* ******************************************************************************************* */
// Для доступа к классу EventEmitter необходимо сделать импорт require('events').EventEmitter.
// Все классы типа EventEmitters вызывают событие 'newListener' при создании нового слушателя событий и вызывают событие 'removeListener' при удаления слушателя событий.
emitter.addListener(event, listener); // Добавляет новый слушатель событий в конец массива слушателей событий данного типа события.
emitter.on(event, listener); // Тоже самое, что и emitter.addListener().
emitter.once(event, listener); // Добавляет новый слушатель данного типа события. Как только данное событие будет вызвано этот слушатель события будет удален.
emitter.removeListener(event, listener); // Удаляет слушатель данного типа событий из массива слушателей событий.
emitter.removeAllListeners([event]); // Удаляет все слушатели события данного типа из массива слушателей событий.
emitter.setMaxListeners(n); // Устанавливает максимальное число слушателей события данного типа, которых можно добавить. Добавление слушателя события сверх этого числа вызовет ошибку.
emitter.listeners(event); // Возвращает массив функций слушателей события данного типа.
emitter.emit(event, [arg1], [arg2], [...]); // Вызывает все слушатели событий данного типа в порядке их добавления с передачей в них прописанных аргументов. Возвращает true, если у данного типа события есть слушатели и false, если нет.
EventEmitter.listenerCount(emitter, event); // Возвращает число созданных слушателей события данного типа.
/* *******************************************************************************************
* Потоки
* http://nodejs.org/api/stream.html
* ******************************************************************************************* */
// Потоки бывают для чтения, для записи и двунаправленные потоки. Все потоки являются экземплярами EventEventEmitter.
// Поток для чтения считывает данные порциями. Он не начнет работать пока вы не укажете начать читать данные.
// Примеры потока для чтения: http responses on the client, http requests on the server, fs read streams, zlib streams, crypto streams, tcp sockets, child process stdout and stderr, process.stdin.
var readable = getReadableStreamSomehow();
readable.on('readable', function() {}); // Вызывается, когда часть данных готова для чтения.
readable.on('data', function(chunk) {}); // Добавление этого слушателя событий переведет поток чтения в автоматический потоковый режим, в котором данные будут автоматически читаться по мере их готовности для чтения.
readable.on('end', function() {}); // Вызывается, когда нет больше данных для чтения.
readable.on('close', function() {}); // Вызывается, когда ресурс для чтения будет закрыт (например будет закрыт открытый файл). Не все потоки излучают подобное событие.
readable.on('error', function() {}); // Вызывается, если произошла ошибка при получении данных для чтения.
// Метод read() вытаскивает данные из внутреннего буфера и передает их потоку чтения. Если в во внутреннем буфере больше нет данных, то он возвращает null.
// Данный метод можно вызывать только в ручном режиме чтения. В автоматическом потоковом режиме чтения этот метод вызывается автоматически до тех пор пока внутренний буфер не опустеет.
readable.read([size]);
readable.setEncoding(encoding); // Заставляет поток возвращать строки в заданной кодировке вместо объектов вида Buffer.
readable.pause(); // Этот метод останавливает автоматический поток чтения и переводит его в ручной пошаговый режим чтения.
readable.resume(); // Этот метод восстанавливает автоматический поток чтения и переводит его из ручной пошагового режима чтения в автоматический.
readable.pipe(destination, [options]); // Этот метод автоматически вытаскивает данные из потока чтения и передаёт их в поток записи.
readable.unpipe([destination]); // Этот метод отменяет действие ранее вызванной функции pipe(). Если destination не задано, то отменяются все ранее созданные функции pipe().
readable.unshift(chunk); // Эта функция полезна в некоторых случаях, когда поток потребляется парсером, который должен "не потреблять" некоторые данные, которые он оптимистически вытащил из источника, чтобы поток мог быть передан какой-либо другой стороне.
// Поток для записи записывает данные порциями.
// Примеры потока для записи: http requests on the client, http responses on the server, fs write streams, zlib streams, crypto streams, tcp sockets, child process stdin, process.stdout, process.stderr.
var writer = getWritableStreamSomehow();
writable.write(chunk, [encoding], [callback]); // Записывает порцию данных и вызывает после этого функцию callback.
writer.once('drain', write); // Если функция writable.write(chunk) вернула false, тогда событие drain укажет когда можно начать запись новых данных в потоке.
writable.end([chunk], [encoding], [callback]); // Вызывается, когда больше не надо записывать данные в потоке записи.
writer.on('finish', function() {}); // Вызывается после того, как будет выполнен метод end() и все данные будут вычищены из внутренней системы
writer.on('pipe', function(src) {}); // Вызывается, когда к потоку записи будет подключен поток чтения с помощью метода pipe().
writer.on('unpipe', function(src) {}); // Вызывается, когда от потока записи будет отключен поток чтения с помощью метода unpipe().
writer.on('error', function(src) {}); // Вызывается, если в потоке записи произойдет ошибка.
// Дуплексные потоки представляют из себя одновременно поток чтения и поток записи.
// Примеры дуплексных потоков: tcp sockets, zlib streams, crypto streams.
// Трансформирующие потоки - это дуплексные потоки, в которых входящие данные для чтения трансформируются и передаются в поток записи.
// Примеры трансформирующих потоков: zlib streams, crypto streams.
/* *******************************************************************************************
* Файловая система
* http://nodejs.org/api/fs.html
* ******************************************************************************************* */
// Для использования этого модуля сделайте импорт require('fs').
// Все методы здесь имеют асинхронную и синхронную версию.
fs.rename(oldPath, newPath, callback); // Асинхронное переименование папки или файла, а также их перемещение.
fs.renameSync(oldPath, newPath); // Синхронное переименование папки или файла, а также их перемещение.
fs.ftruncate(fd, len, callback); // Асинхронное обрезание содержимого открытого файла с данным fd до заданной длины.
fs.ftruncateSync(fd, len); // Синхронное обрезание содержимого открытого файла с данным fd до заданной длины.
fs.truncate(path, len, callback); // Асинхронное обрезание содержимого файла, находящегося по заданному адресу, до заданной длины.
fs.truncateSync(path, len); // Синхронное обрезание содержимого файла, находящегося по заданному адресу, до заданной длины.
fs.chown(path, uid, gid, callback); // Асинхронное изменение владельца данного файла, находящегося по заданному адресу.
fs.chownSync(path, uid, gid); // Синхронное изменение владельца данного файла, находящегося по заданному адресу.
fs.fchown(fd, uid, gid, callback); // Асинхронное изменение владельца данного открытого файла с данным fd.
fs.fchownSync(fd, uid, gid); // Синхронное изменение владельца данного открытого файла с данным fd.
fs.lchown(path, uid, gid, callback); // Асинхронное изменение владельца данного файла, находящегося по заданному адресу.
fs.lchownSync(path, uid, gid); // Синхронное изменение владельца данного файла, находящегося по заданному адресу.
fs.chmod(path, mode, callback); // Асинхронное изменение режима чтения, записи и выполнения данного файла, находящегося по заданному адресу.
fs.chmodSync(path, mode); // Синхронное изменение режима чтения, записи и выполнения данного файла, находящегося по заданному адресу.
fs.fchmod(fd, mode, callback); // Асинхронное изменение режима чтения, записи и выполнения данного открытого файла с данным fd.
fs.fchmodSync(fd, mode); // Синхронное изменение режима чтения, записи и выполнения данного открытого файла с данным fd.
fs.lchmod(path, mode, callback); // Асинхронное изменение режима чтения, записи и выполнения данного файла, находящегося по заданному адресу.
fs.lchmodSync(path, mode); // Синхронное изменение режима чтения, записи и выполнения данного файла, находящегося по заданному адресу.
fs.stat(path, callback); // Асинхронное чтение характеристик данного файла, находящегося по заданному адресу. Аргументы (err, stats), где stats является объектом вида fs.Stats.
fs.statSync(path); // Синхронное чтение характеристик данного файла, находящегося по заданному адресу.
fs.lstat(path, callback); // Асинхронное чтение характеристик данного файла, находящегося по заданному адресу. Аргументы (err, stats), где stats является объектом вида fs.Stats. В отличии от stat(), если path является symbolic link, тогда ссылка сам по себе выводится в stat, а не файл, на который она ссылается.
fs.lstatSync(path); // Синхронное чтение характеристик данного файла, находящегося по заданному адресу.
fs.fstat(fd, callback); // Асинхронное чтение характеристик данного открытого файла с данным fd. Аргументы (err, stats), где stats является объектом вида fs.Stats.
fs.fstatSync(fd); // Синхронное чтение характеристик данного открытого файла с данным fd.
fs.link(srcpath, dstpath, callback); // Асинхронное копирование файла.
fs.linkSync(srcpath, dstpath); // Синхронное копирование файла.
fs.symlink(srcpath, dstpath, [type], callback); // Асинхронное создание символической ссылки файла. Тип может быть: 'dir', 'file', 'junction' (по умолчанию стоит 'file') и доступны только на Windows (другие операционные системы игнорируются).
fs.symlinkSync(srcpath, dstpath, [type]); // Синхронное создание символической ссылки файла. Тип может быть: 'dir', 'file', 'junction' (по умолчанию стоит 'file') и доступны только на Windows (другие операционные системы игнорируются).
fs.readlink(path, callback); // Асинхронное чтение ссылки. callback принимает 2 аргумента (err, linkString).
fs.readlinkSync(path); // Синхронное чтение ссылки.
fs.unlink(path, callback); // Асинхронное удаление файла.
fs.unlinkSync(path); // Синхронное удаление файла.
fs.realpath(path, [cache], callback); // Асинхронное получение реального пути до файла. callback принимает 2 аргумента (err, resolvedPath).
fs.realpathSync(path, [cache]); // Синхронное получение реального пути до файла.
fs.rmdir(path, callback); // Асинхронное удаление директории.
fs.rmdirSync(path); // Синхронное удаление директории.
fs.mkdir(path, [mode], callback); // Асинхронное создание директории. По умолчанию стоит mode 0777.
fs.mkdirSync(path, [mode]); // Синхронное создание директории. По умолчанию стоит mode 0777.
fs.readdir(path, callback); // Асинхронное чтение списка файлов и папок в директории. callback принимает 2 аргумента (err, files), в которых files представляет из себя массив с именами файлов и папок в заданной директории, исключая '.' и '..'.
fs.readdirSync(path); // Синхронное чтение списка файлов и папок в директории.
fs.close(fd, callback); // Асинхронное закрытие открытого файла заданным fd.
fs.closeSync(fd); // Синхронное закрытие открытого файла заданным fd.
fs.open(path, flags, [mode], callback); // Асинхронное открытие файла, находящегося по заданному пути.
fs.openSync(path, flags, [mode]); // Синхронное открытие файла, находящегося по заданному пути.
fs.utimes(path, atime, mtime, callback); // Асинхронное изменение временного штампа файла, находящегося по заданному пути.
fs.utimesSync(path, atime, mtime); // Синхронное изменение временного штампа файла, находящегося по заданному пути.
fs.futimes(fd, atime, mtime, callback); // Асинхронное изменение временного штампа открытого файла, с заданным fd.
fs.futimesSync(fd, atime, mtime); // Синхронное изменение временного штампа открытого файла, с заданным fd.
fs.fsync(fd, callback); // Асинхронное fsync.
fs.fsyncSync(fd); // Синхронное fsync.
fs.write(fd, buffer, offset, length, position, callback); // Асинхронно записать двоичные данные в открытый файл с заданным fd.
fs.writeSync(fd, buffer, offset, length, position); // Синхронно записать двоичные данные в открытый файл с заданным fd.
fs.read(fd, buffer, offset, length, position, callback); // Асинхронно прочитать двоичные данные в открытом файле с заданным fd.
fs.readSync(fd, buffer, offset, length, position); // Синхронно прочитать двоичные данные в открытом файле с заданным fd.
fs.readFile(filename, [options], callback); // Асинхронно прочитать всё содержимое файла сразу. Если задана кодировка, то вернется строка, иначе вернется двоичный буфер с данными.
fs.readFileSync(filename, [options]); // Синхронно прочитать всё содержимое файла сразу. Если задана кодировка, то вернется строка, иначе вернется двоичный буфер с данными.
fs.writeFile(filename, data, [options], callback); // Асинхронно записать данные в файл, полностью замени его, если он уже существует. Данные могу быть строкой или двоичным буфером.
fs.writeFileSync(filename, data, [options]); // Синхронно записать данные в файл, полностью замени его, если он уже существует. Данные могу быть строкой или двоичным буфером.
fs.appendFile(filename, data, [options], callback); // Асинхронно дописать данные в конец файла, если он уже существует или создать файл с новыми данными, если он еще не существует. Данные могу быть строкой или двоичным буфером.
fs.appendFileSync(filename, data, [options]); // Синхронно дописать данные в конец файла, если он уже существует или создать файл с новыми данными, если он еще не существует. Данные могу быть строкой или двоичным буфером.
fs.watch(filename, [options], [listener]); // Отслеживать событие изменения содержимого файла или директории. Возвращает объект s.FSWatcher. callback слушателя принимает 2 аргумента (event, filename). event может быть или 'rename' или'change', а filename - это имя фала, вызвавшего данное событие.
fs.exists(path, callback); // Асинхронно проверить существует ли данный файл и вернуть в функцию callback значение true или false. (не стоит использовать данную функцию)
fs.existsSync(path); // Синхронно проверить существует ли данный файл и вернуть в функцию callback значение true или false. (не стоит использовать данную функцию)
// fs.Stats: объект возвращаемый в функциях fs.stat(), fs.lstat() и fs.fstat() и их синхронных версиях:
stats.isFile();
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink() // (действует только с fs.lstat())
stats.isFIFO()
stats.isSocket()
fs.createReadStream(path, [options]); // Возвращает новый поток чтения из файла.
fs.createWriteStream(path, [options]); // Возвращает новый поток записи в файл.
/* *******************************************************************************************
* Путь
* http://nodejs.org/api/fs.html
* ******************************************************************************************* */
// Для использования этого модуля сделайте импорт require('path').
// Этот модуль содержит функции для обработки и трансформации путей к файлам.
// Почти все эти функции просто трансформируют обычные строки.
// Файловая система не проверяется на существование файлов по данным путям.
path.normalize(p); // Нормализовать строку с путём. Преобразовать '..' и '.' в правильные пути.
path.join([path1], [path2], [...]); // Объединить все части пути в одну строку и нормализовать итоговый путь в строке.
path.resolve([from ...], to); // Определить полный путь до файлаь.
path.relative(from, to); // Определить полный путь для перемещения из директории 'from' в директорию 'to'.
path.dirname(p); // Вернуть путь до директории для заданного пути.
path.basename(p, [ext]); // Вернуть имя файла с расширением для заданного пути.
path.extname(p); // Вернуть расширение файла для заданного пути.
path.sep; // Разделитель в путях файлов для данной операционной системы: '\\' или '/'.
path.delimiter; // Разделитель в путях файлов в переменной окружения для данной операционной системы: ';' or ':'.
/* *******************************************************************************************
* HTTP
* http://nodejs.org/api/http.html
* ******************************************************************************************* */
// Для создания HTTP server и client сделайте импорт require('http').
http.STATUS_CODES; // Объект с набором стандартных кодов HTTP ответов и их текстов.
http.request(options, [callback]); // Функция для отправки запроса на сервер.
http.get(options, [callback]); // Функция для мгновенной отправки GET-запроса на сервер. Не требует отдельного вызоват метода req.end().
server = http.createServer([requestListener]); // Создает сервер. Возвращает объект, который позволяет управлять данным сервером.
server.listen(port, [hostname], [backlog], [callback]); // Начать принимать запросы по заданному port и hostname.
server.listen(path, [callback]); // Стартовать UNIX socket server слушая соединения по заданному пути.
server.listen(handle, [callback]); // Объект handle может быть или сервером или сокетом или fd.
server.close([callback]); // Остановить сервер от приема новых соединений.
server.setTimeout(msecs, callback); // Установить значение таймаута для сокетов и излучить событие 'timeout' для объекта Server, передав socket в качестве аргумента, если случится таймаут.
server.maxHeadersCount; // Ограничить максимальное число входящих заголовков. По умолчанию их число равно 1000. Если задать число 0, то число заголовков будет бесконечным.
server.timeout; // Число миллисекунд неактивности до того, как сокет решит, что произошел таймаут.
server.on('request', function (request, response) { }); // Вызывается каждый раз, как только будет получен новый запрос из браузера.
server.on('connection', function (socket) { }); // Вызывается, когда будет установлено новое TCP соединение.
server.on('close', function () { }); // Вызывается, когда сервер закрывается.
server.on('checkContinue', function (request, response) { }); // Вызывается каждый раз, когда приходит запрос с заголовком Expect: 100-continue.
server.on('connect', function (request, socket, head) { }); // Вызывается каждый раз, когда приходит запрос с типом CONNECT.
server.on('upgrade', function (request, socket, head) { }); // Вызывается каждый раз, когда клиент запрашивает апгрейд соединения.
server.on('clientError', function (exception, socket) { }); // Если клиент излучит событие 'error', то оно будет направлено сюда.
request.write(chunk, [encoding]); // Посылает часть данных на сервер.
request.end([data], [encoding]); // Завершает посылку данных на сервер.
request.abort(); // Обрывает запрос на сервер.
request.setTimeout(timeout, [callback]); // Как только сокет назначен для отправки запроса и соединен с сервером запускается функция socket.setTimeout().
request.setNoDelay([noDelay]); // Как только сокет назначен для отправки запроса и соединен с сервером запускается функция socket.setNoDelay() .
request.setSocketKeepAlive([enable], [initialDelay]); // Как только сокет назначен для отправки запроса и соединен с сервером запускается функция socket.setKeepAlive() .
request.on('response', function(response) { }); // Вызывается как только от сервера получен ответ. Вызывается только 1 раз.
request.on('socket', function(socket) { }); // Вызывается после того. как сокет будет присвоен для отправки запроса на сервер.
request.on('connect', function(response, socket, head) { }); // Emitted each time a server responds to a request with a CONNECT method. If this event isn't being listened for, clients receiving a CONNECT method will have their connections closed.
request.on('upgrade', function(response, socket, head) { }); // Вызывается каждый раз, когда сервер отвечает на запрос апгрейда. Если это событие не слушается, то как только клиент получит заголовок upgrade соединение будет закрыто.
request.on('continue', function() { }); // Вызывается когда сервер посылает ответ '100 Continue', обычно по причине того, что запрос клиента содержал 'Expect: 100-continue'. Это инструкция для того, чтобы клиент послал тело запроса.
response.write(chunk, [encoding]); // Посылает часть данных от сервера клиенту. Если этот метод будет вызван, а метод response.writeHead() не будет вызван, то это очистит неявные заголовки.
response.writeContinue(); // Послать сообщение HTTP/1.1 100 Continue в барузер, означающее, что клиент должен отправить тело запроса .
response.writeHead(statusCode, [reasonPhrase], [headers]); // Посылает заголовок от сервера в браузер.
response.setTimeout(msecs, callback); // Установить значения таймаута сокета в миллисеундах.
response.setHeader(name, value); // Добавить заголовок в заголовки ответа сервера. Если такой заголовок уже существует, то он будет перезаписан. Используйте массив строк, если вы хотите послать множество заголовком с одинаковым именем.
response.getHeader(name); // Прочитать заголовок, который был поставлен в очередь для отправки, но еще не был отправлен в браузер. Имена заголовком чувствительны к регистру.
response.removeHeader(name); // Удалиьь заголовок, который был поставлен в очередь для отправки, но еще не был отправлен в браузер.
response.addTrailers(headers); // Добавить HTTP trailing headers (это такой заголовок, который отправляется в конце сообщения сервера) в ответ сервера.
response.end([data], [encoding]); // Этот метод сигнализирует серверу, что все заголовки и всё тело ответа сервера было отправлено в браузер. Метод response.end() обязательно должен быть вызван в конце каждого ответа сервера.
response.statusCode; // Когда добавляются заголовки (без вызова метода response.writeHead()), это свойство управляет статус кодом ответа, который будет отправлен клиенту, когда заголовки будут отправлены.
response.headersSent; // Булево значение (только для чтения). Равно true если заголовки к этому моменту уже отправлены в браузер, и false, если заголовки еще не были отправлены.
response.sendDate; // Если задано true, то заголовок с датой будет сгенерирован автоматически и отправлен в ответе сервера, если он еще там не присутствует. По умолчанию задано true.
response.on('close', function () { }); // Вызывается, когда соединение разрывается до вызова функции response.end() или всё содержимое отправлено.
response.on('finish', function() { }); // Вызывается, когда всё содержимое отправлено из сервера в браузер.
message.httpVersion; // В случае запроса на сервер версия HTTP отправляется в браузер. В случае ответ ответа клиента этоHTTP версия соединения с сервером.
message.headers; // Объект с заголовками request/response.
message.trailers; // Объект с request/response trailers. Заполняется только после вызова события 'end'.
message.method; // Метод запроса. Строка. Только для чтения. Для примера: 'GET', 'DELETE'.
message.url; // URL запроса. Строка.
message.statusCode; // Код статуса ответа сервера. Например 404.
message.socket; // Объект net.Socket ассоциированный с данным соединением.
message.setTimeout(msecs, callback); // Вызывает message.connection.setTimeout(msecs, callback).
/* *******************************************************************************************
* URL
* http://nodejs.org/api/url.html
* ******************************************************************************************* */
// Этот модуль содержит функции для парсинга URL. Для их использования сделайте импорт require('url').
url.parse(urlStr, [parseQueryString], [slashesDenoteHost]); // Преобразует URL из строки в объект.
url.format(urlObj); // Преобразует объект с URL в строку.
url.resolve(from, to); // Берет базовый (base) URL и href URL и соединяет их так, как если бы это сделал браузер для тэга <a href="..."></a>.
/* *******************************************************************************************
* QUERY STRING
* http://nodejs.org/api/querystring.html
* ******************************************************************************************* */
// Этот модуль предоставляет функции для работы со строками с даннми браузерного запросаT. Для их использования сделайте импорт require('querystring').
querystring.stringify(obj, [sep], [eq]); // Преобразует объект с данными в строку. Опционально можно заменить установленные по умолчанию сепаратор ('&') и символ присваивания ('=').
querystring.parse(str, [sep], [eq], [options]); // Преобразует строку с данными в объект. Опционально можно заменить установленные по умолчанию сепаратор ('&') и символ присваивания ('=').
/* *******************************************************************************************
* ASSERT
* http://nodejs.org/api/assert.html
* ******************************************************************************************* */
// Этот модуль содержит функции для написания юнит-тестов для вашей программы. Для их использования сделайте импорт require('assert').
assert.fail(actual, expected, message, operator); // Выбрасывает исключение, которое отображает актуально и ожидаемое значения, разделенные переданным оператором
assert(value, message); и assert.ok(value, [message]); // Проверят значение на истину. Является эквивалентом функции assert.equal(true, !!value, message);
assert.equal(actual, expected, [message]); // Сравнивает 2 значения с помощью оператора нестрогого равенства ( == ).
assert.notEqual(actual, expected, [message]); // Сравнивает 2 значения с помощью оператора нестрогого неравенства ( != ).
assert.deepEqual(actual, expected, [message]); // Производит глубокую проверку равенства.
assert.notDeepEqual(actual, expected, [message]); // Производит глубокую проверку неравенства.
assert.strictEqual(actual, expected, [message]); // Сравнивает 2 значения с помощью оператора строгого равенства ( === ).
assert.notStrictEqual(actual, expected, [message]); // Сравнивает 2 значения с помощью оператора строгого неравенства ( !== )
assert.throws(block, [error], [message]); // Ожидает, что блок кода выбросит исключение error. error может быть функцией-конструктором, RegExp или функцией валидации значений.
assert.doesNotThrow(block, [message]); // Ожидает, что блок кода не выбросит исключение error. error может быть функцией-конструктором, RegExp или функцией валидации значений.
assert.ifError(value); // Проверяет, что значение не равно false. Выбрасывает исключение, если оно равно true. Полезно для использования, когда первый аргумент является error в функции callbacks.
/* *******************************************************************************************
* Операционная система
* http://nodejs.org/api/os.html
* ******************************************************************************************* */
// Модуль предоставляет функции для получения информации об операционной системе.
// Для их использования сделайте импорт require('os').
os.tmpdir(); // Возвращает путь до директории temp.
os.endianness(); // Возвращает порядок байт процессора. Возможные значения "BE" или "LE".
os.hostname(); // Возвращает имя компьютера.
os.type(); // Возвращает название операционной системы.
os.platform(); // Возвращает вид операционной системы.
os.arch(); // Возвращает тип архитектуры процессора.
os.release(); // Возвращает версию операционной системы.
os.uptime(); // Возвравщает время работы операционной системы в секундах.
os.loadavg(); // Возвращает массив, содержащий 1, 5, и 15 минутные значения средней нагрузки.
os.totalmem(); // Возвращает общее число байт имеющейся оперативной памяти в системе.
os.freemem(); // Возвращает число байт свободной оперативной памяти в системе.
os.cpus(); // Возвращает массив с объектами, содержащими информацию по каждому ядру или процессору, установленному в системе: модель, скорость в мегагерцах и время (объект, содержащий время потраченное ядром процессора на: user, nice, sys, idle, and irq).
os.networkInterfaces(); // Возвращает список доступных сетевых интерфейсов.
os.EOL; // Константа, в которой содержится маркер конца строки для данной операционной системы. Например: \r\n.
/* *******************************************************************************************
* BUFFER
* http://nodejs.org/api/buffer.html
* ******************************************************************************************* */
// Buffer используется для обработки двоичных данных.
// Buffer похож на массив с числами, но он относится к сырой памяти, расположенной вне кучи V8.
Buffer.from(size); // Создает новый буфер с заданным числом октетов.
Buffer.from(array); // Создает новый буфер из массива октетов.
Buffer.from(str, [encoding]); // Создает новый буфер из строки с заданной кодировкой. По умолчанию задана кодировка 'utf8'.
Buffer.isEncoding(encoding); // Возвращает true, если кодировка для буфера допустима и false, если недопустима.
Buffer.isBuffer(obj); // Проверяет является ли объекто буффером.
Buffer.concat(list, [totalLength]); // Объединяет несколько буферов в один.
Buffer.byteLength(string, [encoding]); // Возвращает дину строки в байтах.
buf.write(string, [offset], [length], [encoding]); // Записывает строку в буфер с учетом смещения и заданной кодировки.
buf.toString([encoding], [start], [end]); // Преобразует буфер в строку с учетом кодировки (по умолчанию задана кодировка 'utf8') и начала (по умолчанию задано 0) и конца буфера (по умолчанию равно buffer.length).
buf.toJSON(); // Преобразует буфер в формат JSON.
buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd]); // Копирует значения из одного буфера в другой буфер. Исходная и целевая области буфера могут перекрываться.
buf.slice([start], [end]); // Возвращает новый буфер, в который ссылается на ту же область памяти, что и старый, но со смещением offset и обрезанием от стартового start (по умолчанию равно 0) до конечного end индекса (по умолчанию равно buffer.length). Отрицательные индексы допустимы.
buf.fill(value, [offset], [end]); // Заполняет этот буфер заданными значениями. Если в буфере есть значения, то они заменяются заданными.
buf[index]; // Получить и установить октет буфера с данным индексом.
buf.length; // Размер буфера в байтах. The size of the buffer in bytes, Обратите внимание, что это не обязательно размер содержимого.
buffer.INSPECT_MAX_BYTES; // Сколько байт максимально может быть возвращено функцией buffer.inspect(). Это значение может быть перезаписано пользователем данного модуля.
* Краткий обзор
* http://nodejs.org/api/synopsis.html
* ******************************************************************************************* */
var http = require('http');
// Пример сервера, оправляющего в браузер ответ 'Hello World'.
// Для запуска сервера поместите код в файл с именем example.js и выполните его с помощью Node.js.
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World');
}).listen(8000);
console.log('Сервер запущен по адресу http://127.0.0.1:8000/');
/* *******************************************************************************************
* Глобальные объекты
* http://nodejs.org/api/globals.html
* ******************************************************************************************* */
__filename; // Абсолютный путь до файла, код которого выполняется.
__dirname; // Абсолютный путь до директории, в которой находится файл с выполняемым кодом.
module; // Ссылка на текущий модуль. В частности module.exports используется для определения того, что модуль экспортирует и делает доступным для загрузки через require().
exports; // Укороченная ссылка на module.exports.
process; // Глобальный объект текущего запущенного процесса Node.js. Доступен везде. Является экземпляром класса EventEmitter.
Buffer; // Глобальный класс для работы напрямую с двоичными данными.
/* *******************************************************************************************
* Консоль
* http://nodejs.org/api/console.html
* ******************************************************************************************* */
console.log([data], [...]); // Печатает текст вместе с символом перевода на новую строку на конце в stdout командного терминала.
console.info([data], [...]); // Тоже самое, что и console.log.
console.error([data], [...]); // Тоже самое, что и console.log, но печатает текст в stderr командного терминала.
console.warn([data], [...]); // Тоже самое, что и console.error.
console.dir(obj); // Использует util.inspect на obj и печатает итоговую строку с текстом в stdout командного терминала.
console.time(label); // Запускает замер времени.
console.timeEnd(label); // Останавливает замер времени и выводит итоговое время в stdout командного терминала.
console.trace(label); // Печатает содержимое стека (stack trace) в данный момент в stderr командного терминала.
console.assert(expression, [message]); // Тоже самое, что и assert.ok(), в котором, если выполняемое выражение получает в итоге значение false, то выбрасывается исключение AssertionError с соответствующим сообщением.
/* *******************************************************************************************
* Таймеры
* http://nodejs.org/api/timers.html
* ******************************************************************************************* */
setTimeout(callback, delay, [arg], [...]); // Выполняет функцию callback один раз через указанное число миллисекунд. В функцию callback также можно передать указанные аргументы.
clearTimeout(t); // Отменяет выполнение ранее созданного таймера с помощью функции setTimeout().
setInterval(callback, delay, [arg], [...]); // Повторно выполняет функцию callback через заданное число миллисекунд до тех пор, пока не будет отменено с помощью функции clearInterval(). В функцию callback также можно передать указанные аргументы.
clearInterval(t); // Отменяет выполнение ранее созданного таймера с помощью функции setInterval().
setImmediate(callback, [arg], [...]); // Немедленно выполняет функцию callback после выполнения всех операций ввода-вывода и до setTimeout и setInterval.
clearImmediate(immediateObject); // Отменяет выполнение ранее созданного таймера с помощью функции setImmediate().
unref(); // Позволяет создавать таймер, который будет активен только до того момента, пока программа Node.js выполняется и есть активные элементы в цикле event loop. После завершения всех операций в цикле event loop программа будет закрыта.
ref(); // Если вы ранее выполнили функцию unref() для таймера, то вы можете выполнить функцию ref(), которая позволит таймеру удерживать вашу программу от закрытия после того, как все операции в цикле event loop будут завершены.
/* *******************************************************************************************
* Модули
* http://nodejs.org/api/modules.html
* ******************************************************************************************* */
var module = require('./file.js'); // Загружает модуль file.js, находящийся в той же директории.
module.require('./another_file.js'); // Загружает модуль another_file.js так, как если бы функция require() была вызвана самим модулем.
module.id; // Идентификатор модуля. Обычно это путь до файла.
module.filename; // Абсолютный путь до файла с его именем.
module.loaded; // Загружен ли уже модуль или он всё ещё загружается.
module.parent; // Родительский модуль, который загрузил данный модуль.
module.children; // Дочерние модули, которые загрузил данный модуль через функцию require().
// Экспорт из модуля функции с именем area.
exports.area = function (r) {
return Math.PI * r * r;
};
// module.exports - это объект с перечнем экспортируемых из данного модуля элементов.
// Если вы хотите, то можете превратить его в функцию, например функцию-конструктор, которая будет создавать экспортируемые объекты или вы можете присвоить ему экспортируемый объект, в котором находятся все экспортируемые элементы сразу.
// Присвоение значения module.exports затирает значения в exports.
module.exports = function(width) {
return {
area: function() {
return width * width;
}
};
}
/* *******************************************************************************************
* Процесс
* http://nodejs.org/api/process.html
* ******************************************************************************************* */
process.on('exit', function(code) {}); // Функция вызывается, когда процесс Node.js завершается и происходит выход из программы.
process.on('uncaughtException', function(err) {}); // Функция вызывается, когда появляется никем не перехваченное исключение. В этом случае программа не вылетает и продолжает работать выполняться со сбоем, поэтому не стоит эту функцию использовать.
process.stdout; // Поток для записи в stdout командного терминала.
process.stderr; // Поток для записи в stderr командного терминала.
process.stdin; // Поток чтения из stdin командного терминала.
process.argv; // Массив, содержащий все аргументы, переданные из командной строки терминала во время запуска программы.
process.env; // Объект, содержащий значения переменных среды окружения (например значение переменной среды Path из Windows).
process.execPath; // Абсолютный путь до файла node.exe, который запустил данную JavaSctipt-программу.
process.execArgv; // Массив, содержащий все аргументы командных опций Node.js, которые были введены при запуске программы.
process.arch; // Архитектура процессора системы: 'arm', 'ia32', 'x64'.
process.config; // Объект, содержащий в себе конфигурационные опции, которые были использованы для компиляции и создания текущего файла node.exe.
process.pid; // Идентификатор текущего запущенного процесса PID .
process.platform; // Операционная система, в которой запущена данная программа: 'darwin', 'freebsd', 'linux', 'sunos', 'win32'.
process.title; // Getter/setter для установки имени процесса для отображения в 'ps'. (Например C:\\WINDOWS\\system32\\cmd.exe - node)
process.version; // Версия Node.js.
process.versions; // Версия Node.js и некоторых его внутренних модулей.
process.abort(); // Прервать выполнение программы. Это заставит Node.js выйти из программы и сгенерировать core file.
process.chdir(dir); // Изменить текущую рабочую директорию, из которой была запущена программа. Выбрасывает исключение, если изменить текущую рабочую директорию невозможно.
process.cwd(); // Текущая рабочая директория, из которой была запущена программа.
process.exit([code]); // Завершить программу с заданным кодом. Если код не задан, то программ успешно завершится с кодом 0.
process.getgid(); // Получить идентификатор группы пользователей данного процесса.
process.setgid(id); // Установить идентификатор группы пользователей данного процесса.
process.getuid(); // Получить идентификатор пользователя данного процесса.
process.setuid(id); // Установить идентификатор пользователя данного процесса.
process.getgroups(); // Получить массив с идентификаторами дополнительных групп пользователей.
process.setgroups(grps); // Установить идентификаторы дополнительных групп пользователей.
process.initgroups(user, extra_grp); // Читает содержимое /etc/group и инициализирует лист доступа для группы, использую группы, к которых данный пользователь является их членом.
process.kill(pid, [signal]); // Посылает сигнал signal процессу с идентификатором pid.
process.memoryUsage(); // Возвращает объект, описывающий использование памяти данным процессом Node.js в байтах.
process.nextTick(callback); // Вызвать функцию callback на следующем шаге цикла event loop.
process.maxTickDepth; // Обратные вызовы, переданные процессу .nextTick обычно вызывается в конце текущего потока выполнения и, таким образом, примерно так же быстро, как вызов функции синхронно.
process.umask([mask]); // Устанавливает или считывает маску создания процесса файла.
process.uptime(); // Время выполнения данной программы в секундах.
process.hrtime(); // Текущее время в высоком разрешении в формате массива [seconds, nanoseconds] (удобно для точного замера времени выполнения какой-либо функции).
/* *******************************************************************************************
* Дочерний процесс
* http://nodejs.org/api/child_process.html
* ******************************************************************************************* */
// Дочерний процесс - это отдельная Node.js программа, запускаемая из родительской Node.js программы.
ChildProcess; // Класс. ChildProcess является EventEmitter.
child.stdin; // Поток ввода дочернего процесса stdin.
child.stdout; // Поток вывода дочернего процесса stdout.
child.stderr; // Поток вывода ошибок дочернего процесса stderr.
child.pid; // Идентификатор дочернего процесса PID.
child.connected; // Если .connected равно false, то больше невозможно посылать сообщения в дочерний процесс из родительского процесса.
child.kill([signal]); // Послать сигнал signal в дочерний процесс.
child.send(message, [sendHandle]); // После создания дочернего процесса с помощью функции child_process.fork() вы можете отправлять в дочерний процесс данные с помощью функции child.send(message, [sendHandle]) и получать их в дочернем процессе с помощью события .on('message', callback).
child.disconnect(); // Закрыть канал передачи данных IPC между родительским и дочерним процессом. channel between parent and child, что позволяет дочернему процессу завершить своё выполнение, поскольку больше никаких соединений с ним не установлено.
child_process.spawn(command, [args], [options]); // Запускает дочерний процесс с переданными в него аргументами. Передача данных в дочерний процесс или из него осуществляется через потоки streams.
child_process.exec(command, [options], callback); // Выполняет команду в командном терминале и возвращает результат её выполнения.
child_process.execFile(file, [args], [options], [callback]); // Выполняет файл в командном терминале и возвращает результат его выполнения.
child_process.fork(modulePath, [args], [options]); // Особая форма функции spawn(), которая выполняет JavaScript-файл, как отдельную Node.js программу. Общение между родительской и дочерней программой производится через посылку друг другу сообщений messafe.
/* *******************************************************************************************
* Утилиты
* http://nodejs.org/api/util.html
* ******************************************************************************************* */
// Эти функции содержатся в модуле 'util'. Используйте require('util') для получения доступа к ним.
util.format(format, [...]); // Возвращает отформатированную строку. Символы для подстановки строкиЮ числа и данных в формате JSON: %s, %d, %j
util.debug(string); // Функция для синхронного вывода текста в stderr командного терминала.
util.error([...]); // Тоже самое. что и util.debug(), но только выводит все аргументы stderr командного терминала.
util.puts([...]); // Функция для синхронного вывода текста в stdout командного терминала с символом новой строки после каждого аргумента.
util.print([...]); // Функция для синхронного вывода текста в stdout командного терминала без символов новой строки после каждого аргумента.
util.log(string); // Выводит текст вместе с временной меткой в stdout командного терминала.
util.inspect(object, [opts]); // Выводит объект в виде строки, что удобно для поиска багов. (Опции: showHidden, depth, colors, customInspect)
util.isArray(object); // Возвращает true, если переданный объект является массивом и false, если нет.
util.isRegExp(object); // Возвращает true, если переданный объект является регулярным выражением и false, если нет.
util.isDate(object); // Возвращает true, если переданный объект является датой и false, если нет.
util.isError(object); // Возвращает true, если переданный объект является объектом Error и false, если нет.
util.promisify(fn); // Берет функцию, в которой последний аргумент является callback-функцией и превращает её в функцию, возвращающую promise.
util.inherits(constructor, superConstructor); // Копирует методы прототипа из одной функции конструктора в другую функцию конструктор.
/* *******************************************************************************************
* События
* http://nodejs.org/api/events.html
* ******************************************************************************************* */
// Для доступа к классу EventEmitter необходимо сделать импорт require('events').EventEmitter.
// Все классы типа EventEmitters вызывают событие 'newListener' при создании нового слушателя событий и вызывают событие 'removeListener' при удаления слушателя событий.
emitter.addListener(event, listener); // Добавляет новый слушатель событий в конец массива слушателей событий данного типа события.
emitter.on(event, listener); // Тоже самое, что и emitter.addListener().
emitter.once(event, listener); // Добавляет новый слушатель данного типа события. Как только данное событие будет вызвано этот слушатель события будет удален.
emitter.removeListener(event, listener); // Удаляет слушатель данного типа событий из массива слушателей событий.
emitter.removeAllListeners([event]); // Удаляет все слушатели события данного типа из массива слушателей событий.
emitter.setMaxListeners(n); // Устанавливает максимальное число слушателей события данного типа, которых можно добавить. Добавление слушателя события сверх этого числа вызовет ошибку.
emitter.listeners(event); // Возвращает массив функций слушателей события данного типа.
emitter.emit(event, [arg1], [arg2], [...]); // Вызывает все слушатели событий данного типа в порядке их добавления с передачей в них прописанных аргументов. Возвращает true, если у данного типа события есть слушатели и false, если нет.
EventEmitter.listenerCount(emitter, event); // Возвращает число созданных слушателей события данного типа.
/* *******************************************************************************************
* Потоки
* http://nodejs.org/api/stream.html
* ******************************************************************************************* */
// Потоки бывают для чтения, для записи и двунаправленные потоки. Все потоки являются экземплярами EventEventEmitter.
// Поток для чтения считывает данные порциями. Он не начнет работать пока вы не укажете начать читать данные.
// Примеры потока для чтения: http responses on the client, http requests on the server, fs read streams, zlib streams, crypto streams, tcp sockets, child process stdout and stderr, process.stdin.
var readable = getReadableStreamSomehow();
readable.on('readable', function() {}); // Вызывается, когда часть данных готова для чтения.
readable.on('data', function(chunk) {}); // Добавление этого слушателя событий переведет поток чтения в автоматический потоковый режим, в котором данные будут автоматически читаться по мере их готовности для чтения.
readable.on('end', function() {}); // Вызывается, когда нет больше данных для чтения.
readable.on('close', function() {}); // Вызывается, когда ресурс для чтения будет закрыт (например будет закрыт открытый файл). Не все потоки излучают подобное событие.
readable.on('error', function() {}); // Вызывается, если произошла ошибка при получении данных для чтения.
// Метод read() вытаскивает данные из внутреннего буфера и передает их потоку чтения. Если в во внутреннем буфере больше нет данных, то он возвращает null.
// Данный метод можно вызывать только в ручном режиме чтения. В автоматическом потоковом режиме чтения этот метод вызывается автоматически до тех пор пока внутренний буфер не опустеет.
readable.read([size]);
readable.setEncoding(encoding); // Заставляет поток возвращать строки в заданной кодировке вместо объектов вида Buffer.
readable.pause(); // Этот метод останавливает автоматический поток чтения и переводит его в ручной пошаговый режим чтения.
readable.resume(); // Этот метод восстанавливает автоматический поток чтения и переводит его из ручной пошагового режима чтения в автоматический.
readable.pipe(destination, [options]); // Этот метод автоматически вытаскивает данные из потока чтения и передаёт их в поток записи.
readable.unpipe([destination]); // Этот метод отменяет действие ранее вызванной функции pipe(). Если destination не задано, то отменяются все ранее созданные функции pipe().
readable.unshift(chunk); // Эта функция полезна в некоторых случаях, когда поток потребляется парсером, который должен "не потреблять" некоторые данные, которые он оптимистически вытащил из источника, чтобы поток мог быть передан какой-либо другой стороне.
// Поток для записи записывает данные порциями.
// Примеры потока для записи: http requests on the client, http responses on the server, fs write streams, zlib streams, crypto streams, tcp sockets, child process stdin, process.stdout, process.stderr.
var writer = getWritableStreamSomehow();
writable.write(chunk, [encoding], [callback]); // Записывает порцию данных и вызывает после этого функцию callback.
writer.once('drain', write); // Если функция writable.write(chunk) вернула false, тогда событие drain укажет когда можно начать запись новых данных в потоке.
writable.end([chunk], [encoding], [callback]); // Вызывается, когда больше не надо записывать данные в потоке записи.
writer.on('finish', function() {}); // Вызывается после того, как будет выполнен метод end() и все данные будут вычищены из внутренней системы
writer.on('pipe', function(src) {}); // Вызывается, когда к потоку записи будет подключен поток чтения с помощью метода pipe().
writer.on('unpipe', function(src) {}); // Вызывается, когда от потока записи будет отключен поток чтения с помощью метода unpipe().
writer.on('error', function(src) {}); // Вызывается, если в потоке записи произойдет ошибка.
// Дуплексные потоки представляют из себя одновременно поток чтения и поток записи.
// Примеры дуплексных потоков: tcp sockets, zlib streams, crypto streams.
// Трансформирующие потоки - это дуплексные потоки, в которых входящие данные для чтения трансформируются и передаются в поток записи.
// Примеры трансформирующих потоков: zlib streams, crypto streams.
/* *******************************************************************************************
* Файловая система
* http://nodejs.org/api/fs.html
* ******************************************************************************************* */
// Для использования этого модуля сделайте импорт require('fs').
// Все методы здесь имеют асинхронную и синхронную версию.
fs.rename(oldPath, newPath, callback); // Асинхронное переименование папки или файла, а также их перемещение.
fs.renameSync(oldPath, newPath); // Синхронное переименование папки или файла, а также их перемещение.
fs.ftruncate(fd, len, callback); // Асинхронное обрезание содержимого открытого файла с данным fd до заданной длины.
fs.ftruncateSync(fd, len); // Синхронное обрезание содержимого открытого файла с данным fd до заданной длины.
fs.truncate(path, len, callback); // Асинхронное обрезание содержимого файла, находящегося по заданному адресу, до заданной длины.
fs.truncateSync(path, len); // Синхронное обрезание содержимого файла, находящегося по заданному адресу, до заданной длины.
fs.chown(path, uid, gid, callback); // Асинхронное изменение владельца данного файла, находящегося по заданному адресу.
fs.chownSync(path, uid, gid); // Синхронное изменение владельца данного файла, находящегося по заданному адресу.
fs.fchown(fd, uid, gid, callback); // Асинхронное изменение владельца данного открытого файла с данным fd.
fs.fchownSync(fd, uid, gid); // Синхронное изменение владельца данного открытого файла с данным fd.
fs.lchown(path, uid, gid, callback); // Асинхронное изменение владельца данного файла, находящегося по заданному адресу.
fs.lchownSync(path, uid, gid); // Синхронное изменение владельца данного файла, находящегося по заданному адресу.
fs.chmod(path, mode, callback); // Асинхронное изменение режима чтения, записи и выполнения данного файла, находящегося по заданному адресу.
fs.chmodSync(path, mode); // Синхронное изменение режима чтения, записи и выполнения данного файла, находящегося по заданному адресу.
fs.fchmod(fd, mode, callback); // Асинхронное изменение режима чтения, записи и выполнения данного открытого файла с данным fd.
fs.fchmodSync(fd, mode); // Синхронное изменение режима чтения, записи и выполнения данного открытого файла с данным fd.
fs.lchmod(path, mode, callback); // Асинхронное изменение режима чтения, записи и выполнения данного файла, находящегося по заданному адресу.
fs.lchmodSync(path, mode); // Синхронное изменение режима чтения, записи и выполнения данного файла, находящегося по заданному адресу.
fs.stat(path, callback); // Асинхронное чтение характеристик данного файла, находящегося по заданному адресу. Аргументы (err, stats), где stats является объектом вида fs.Stats.
fs.statSync(path); // Синхронное чтение характеристик данного файла, находящегося по заданному адресу.
fs.lstat(path, callback); // Асинхронное чтение характеристик данного файла, находящегося по заданному адресу. Аргументы (err, stats), где stats является объектом вида fs.Stats. В отличии от stat(), если path является symbolic link, тогда ссылка сам по себе выводится в stat, а не файл, на который она ссылается.
fs.lstatSync(path); // Синхронное чтение характеристик данного файла, находящегося по заданному адресу.
fs.fstat(fd, callback); // Асинхронное чтение характеристик данного открытого файла с данным fd. Аргументы (err, stats), где stats является объектом вида fs.Stats.
fs.fstatSync(fd); // Синхронное чтение характеристик данного открытого файла с данным fd.
fs.link(srcpath, dstpath, callback); // Асинхронное копирование файла.
fs.linkSync(srcpath, dstpath); // Синхронное копирование файла.
fs.symlink(srcpath, dstpath, [type], callback); // Асинхронное создание символической ссылки файла. Тип может быть: 'dir', 'file', 'junction' (по умолчанию стоит 'file') и доступны только на Windows (другие операционные системы игнорируются).
fs.symlinkSync(srcpath, dstpath, [type]); // Синхронное создание символической ссылки файла. Тип может быть: 'dir', 'file', 'junction' (по умолчанию стоит 'file') и доступны только на Windows (другие операционные системы игнорируются).
fs.readlink(path, callback); // Асинхронное чтение ссылки. callback принимает 2 аргумента (err, linkString).
fs.readlinkSync(path); // Синхронное чтение ссылки.
fs.unlink(path, callback); // Асинхронное удаление файла.
fs.unlinkSync(path); // Синхронное удаление файла.
fs.realpath(path, [cache], callback); // Асинхронное получение реального пути до файла. callback принимает 2 аргумента (err, resolvedPath).
fs.realpathSync(path, [cache]); // Синхронное получение реального пути до файла.
fs.rmdir(path, callback); // Асинхронное удаление директории.
fs.rmdirSync(path); // Синхронное удаление директории.
fs.mkdir(path, [mode], callback); // Асинхронное создание директории. По умолчанию стоит mode 0777.
fs.mkdirSync(path, [mode]); // Синхронное создание директории. По умолчанию стоит mode 0777.
fs.readdir(path, callback); // Асинхронное чтение списка файлов и папок в директории. callback принимает 2 аргумента (err, files), в которых files представляет из себя массив с именами файлов и папок в заданной директории, исключая '.' и '..'.
fs.readdirSync(path); // Синхронное чтение списка файлов и папок в директории.
fs.close(fd, callback); // Асинхронное закрытие открытого файла заданным fd.
fs.closeSync(fd); // Синхронное закрытие открытого файла заданным fd.
fs.open(path, flags, [mode], callback); // Асинхронное открытие файла, находящегося по заданному пути.
fs.openSync(path, flags, [mode]); // Синхронное открытие файла, находящегося по заданному пути.
fs.utimes(path, atime, mtime, callback); // Асинхронное изменение временного штампа файла, находящегося по заданному пути.
fs.utimesSync(path, atime, mtime); // Синхронное изменение временного штампа файла, находящегося по заданному пути.
fs.futimes(fd, atime, mtime, callback); // Асинхронное изменение временного штампа открытого файла, с заданным fd.
fs.futimesSync(fd, atime, mtime); // Синхронное изменение временного штампа открытого файла, с заданным fd.
fs.fsync(fd, callback); // Асинхронное fsync.
fs.fsyncSync(fd); // Синхронное fsync.
fs.write(fd, buffer, offset, length, position, callback); // Асинхронно записать двоичные данные в открытый файл с заданным fd.
fs.writeSync(fd, buffer, offset, length, position); // Синхронно записать двоичные данные в открытый файл с заданным fd.
fs.read(fd, buffer, offset, length, position, callback); // Асинхронно прочитать двоичные данные в открытом файле с заданным fd.
fs.readSync(fd, buffer, offset, length, position); // Синхронно прочитать двоичные данные в открытом файле с заданным fd.
fs.readFile(filename, [options], callback); // Асинхронно прочитать всё содержимое файла сразу. Если задана кодировка, то вернется строка, иначе вернется двоичный буфер с данными.
fs.readFileSync(filename, [options]); // Синхронно прочитать всё содержимое файла сразу. Если задана кодировка, то вернется строка, иначе вернется двоичный буфер с данными.
fs.writeFile(filename, data, [options], callback); // Асинхронно записать данные в файл, полностью замени его, если он уже существует. Данные могу быть строкой или двоичным буфером.
fs.writeFileSync(filename, data, [options]); // Синхронно записать данные в файл, полностью замени его, если он уже существует. Данные могу быть строкой или двоичным буфером.
fs.appendFile(filename, data, [options], callback); // Асинхронно дописать данные в конец файла, если он уже существует или создать файл с новыми данными, если он еще не существует. Данные могу быть строкой или двоичным буфером.
fs.appendFileSync(filename, data, [options]); // Синхронно дописать данные в конец файла, если он уже существует или создать файл с новыми данными, если он еще не существует. Данные могу быть строкой или двоичным буфером.
fs.watch(filename, [options], [listener]); // Отслеживать событие изменения содержимого файла или директории. Возвращает объект s.FSWatcher. callback слушателя принимает 2 аргумента (event, filename). event может быть или 'rename' или'change', а filename - это имя фала, вызвавшего данное событие.
fs.exists(path, callback); // Асинхронно проверить существует ли данный файл и вернуть в функцию callback значение true или false. (не стоит использовать данную функцию)
fs.existsSync(path); // Синхронно проверить существует ли данный файл и вернуть в функцию callback значение true или false. (не стоит использовать данную функцию)
// fs.Stats: объект возвращаемый в функциях fs.stat(), fs.lstat() и fs.fstat() и их синхронных версиях:
stats.isFile();
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink() // (действует только с fs.lstat())
stats.isFIFO()
stats.isSocket()
fs.createReadStream(path, [options]); // Возвращает новый поток чтения из файла.
fs.createWriteStream(path, [options]); // Возвращает новый поток записи в файл.
/* *******************************************************************************************
* Путь
* http://nodejs.org/api/fs.html
* ******************************************************************************************* */
// Для использования этого модуля сделайте импорт require('path').
// Этот модуль содержит функции для обработки и трансформации путей к файлам.
// Почти все эти функции просто трансформируют обычные строки.
// Файловая система не проверяется на существование файлов по данным путям.
path.normalize(p); // Нормализовать строку с путём. Преобразовать '..' и '.' в правильные пути.
path.join([path1], [path2], [...]); // Объединить все части пути в одну строку и нормализовать итоговый путь в строке.
path.resolve([from ...], to); // Определить полный путь до файлаь.
path.relative(from, to); // Определить полный путь для перемещения из директории 'from' в директорию 'to'.
path.dirname(p); // Вернуть путь до директории для заданного пути.
path.basename(p, [ext]); // Вернуть имя файла с расширением для заданного пути.
path.extname(p); // Вернуть расширение файла для заданного пути.
path.sep; // Разделитель в путях файлов для данной операционной системы: '\\' или '/'.
path.delimiter; // Разделитель в путях файлов в переменной окружения для данной операционной системы: ';' or ':'.
/* *******************************************************************************************
* HTTP
* http://nodejs.org/api/http.html
* ******************************************************************************************* */
// Для создания HTTP server и client сделайте импорт require('http').
http.STATUS_CODES; // Объект с набором стандартных кодов HTTP ответов и их текстов.
http.request(options, [callback]); // Функция для отправки запроса на сервер.
http.get(options, [callback]); // Функция для мгновенной отправки GET-запроса на сервер. Не требует отдельного вызоват метода req.end().
server = http.createServer([requestListener]); // Создает сервер. Возвращает объект, который позволяет управлять данным сервером.
server.listen(port, [hostname], [backlog], [callback]); // Начать принимать запросы по заданному port и hostname.
server.listen(path, [callback]); // Стартовать UNIX socket server слушая соединения по заданному пути.
server.listen(handle, [callback]); // Объект handle может быть или сервером или сокетом или fd.
server.close([callback]); // Остановить сервер от приема новых соединений.
server.setTimeout(msecs, callback); // Установить значение таймаута для сокетов и излучить событие 'timeout' для объекта Server, передав socket в качестве аргумента, если случится таймаут.
server.maxHeadersCount; // Ограничить максимальное число входящих заголовков. По умолчанию их число равно 1000. Если задать число 0, то число заголовков будет бесконечным.
server.timeout; // Число миллисекунд неактивности до того, как сокет решит, что произошел таймаут.
server.on('request', function (request, response) { }); // Вызывается каждый раз, как только будет получен новый запрос из браузера.
server.on('connection', function (socket) { }); // Вызывается, когда будет установлено новое TCP соединение.
server.on('close', function () { }); // Вызывается, когда сервер закрывается.
server.on('checkContinue', function (request, response) { }); // Вызывается каждый раз, когда приходит запрос с заголовком Expect: 100-continue.
server.on('connect', function (request, socket, head) { }); // Вызывается каждый раз, когда приходит запрос с типом CONNECT.
server.on('upgrade', function (request, socket, head) { }); // Вызывается каждый раз, когда клиент запрашивает апгрейд соединения.
server.on('clientError', function (exception, socket) { }); // Если клиент излучит событие 'error', то оно будет направлено сюда.
request.write(chunk, [encoding]); // Посылает часть данных на сервер.
request.end([data], [encoding]); // Завершает посылку данных на сервер.
request.abort(); // Обрывает запрос на сервер.
request.setTimeout(timeout, [callback]); // Как только сокет назначен для отправки запроса и соединен с сервером запускается функция socket.setTimeout().
request.setNoDelay([noDelay]); // Как только сокет назначен для отправки запроса и соединен с сервером запускается функция socket.setNoDelay() .
request.setSocketKeepAlive([enable], [initialDelay]); // Как только сокет назначен для отправки запроса и соединен с сервером запускается функция socket.setKeepAlive() .
request.on('response', function(response) { }); // Вызывается как только от сервера получен ответ. Вызывается только 1 раз.
request.on('socket', function(socket) { }); // Вызывается после того. как сокет будет присвоен для отправки запроса на сервер.
request.on('connect', function(response, socket, head) { }); // Emitted each time a server responds to a request with a CONNECT method. If this event isn't being listened for, clients receiving a CONNECT method will have their connections closed.
request.on('upgrade', function(response, socket, head) { }); // Вызывается каждый раз, когда сервер отвечает на запрос апгрейда. Если это событие не слушается, то как только клиент получит заголовок upgrade соединение будет закрыто.
request.on('continue', function() { }); // Вызывается когда сервер посылает ответ '100 Continue', обычно по причине того, что запрос клиента содержал 'Expect: 100-continue'. Это инструкция для того, чтобы клиент послал тело запроса.
response.write(chunk, [encoding]); // Посылает часть данных от сервера клиенту. Если этот метод будет вызван, а метод response.writeHead() не будет вызван, то это очистит неявные заголовки.
response.writeContinue(); // Послать сообщение HTTP/1.1 100 Continue в барузер, означающее, что клиент должен отправить тело запроса .
response.writeHead(statusCode, [reasonPhrase], [headers]); // Посылает заголовок от сервера в браузер.
response.setTimeout(msecs, callback); // Установить значения таймаута сокета в миллисеундах.
response.setHeader(name, value); // Добавить заголовок в заголовки ответа сервера. Если такой заголовок уже существует, то он будет перезаписан. Используйте массив строк, если вы хотите послать множество заголовком с одинаковым именем.
response.getHeader(name); // Прочитать заголовок, который был поставлен в очередь для отправки, но еще не был отправлен в браузер. Имена заголовком чувствительны к регистру.
response.removeHeader(name); // Удалиьь заголовок, который был поставлен в очередь для отправки, но еще не был отправлен в браузер.
response.addTrailers(headers); // Добавить HTTP trailing headers (это такой заголовок, который отправляется в конце сообщения сервера) в ответ сервера.
response.end([data], [encoding]); // Этот метод сигнализирует серверу, что все заголовки и всё тело ответа сервера было отправлено в браузер. Метод response.end() обязательно должен быть вызван в конце каждого ответа сервера.
response.statusCode; // Когда добавляются заголовки (без вызова метода response.writeHead()), это свойство управляет статус кодом ответа, который будет отправлен клиенту, когда заголовки будут отправлены.
response.headersSent; // Булево значение (только для чтения). Равно true если заголовки к этому моменту уже отправлены в браузер, и false, если заголовки еще не были отправлены.
response.sendDate; // Если задано true, то заголовок с датой будет сгенерирован автоматически и отправлен в ответе сервера, если он еще там не присутствует. По умолчанию задано true.
response.on('close', function () { }); // Вызывается, когда соединение разрывается до вызова функции response.end() или всё содержимое отправлено.
response.on('finish', function() { }); // Вызывается, когда всё содержимое отправлено из сервера в браузер.
message.httpVersion; // В случае запроса на сервер версия HTTP отправляется в браузер. В случае ответ ответа клиента этоHTTP версия соединения с сервером.
message.headers; // Объект с заголовками request/response.
message.trailers; // Объект с request/response trailers. Заполняется только после вызова события 'end'.
message.method; // Метод запроса. Строка. Только для чтения. Для примера: 'GET', 'DELETE'.
message.url; // URL запроса. Строка.
message.statusCode; // Код статуса ответа сервера. Например 404.
message.socket; // Объект net.Socket ассоциированный с данным соединением.
message.setTimeout(msecs, callback); // Вызывает message.connection.setTimeout(msecs, callback).
/* *******************************************************************************************
* URL
* http://nodejs.org/api/url.html
* ******************************************************************************************* */
// Этот модуль содержит функции для парсинга URL. Для их использования сделайте импорт require('url').
url.parse(urlStr, [parseQueryString], [slashesDenoteHost]); // Преобразует URL из строки в объект.
url.format(urlObj); // Преобразует объект с URL в строку.
url.resolve(from, to); // Берет базовый (base) URL и href URL и соединяет их так, как если бы это сделал браузер для тэга <a href="..."></a>.
/* *******************************************************************************************
* QUERY STRING
* http://nodejs.org/api/querystring.html
* ******************************************************************************************* */
// Этот модуль предоставляет функции для работы со строками с даннми браузерного запросаT. Для их использования сделайте импорт require('querystring').
querystring.stringify(obj, [sep], [eq]); // Преобразует объект с данными в строку. Опционально можно заменить установленные по умолчанию сепаратор ('&') и символ присваивания ('=').
querystring.parse(str, [sep], [eq], [options]); // Преобразует строку с данными в объект. Опционально можно заменить установленные по умолчанию сепаратор ('&') и символ присваивания ('=').
/* *******************************************************************************************
* ASSERT
* http://nodejs.org/api/assert.html
* ******************************************************************************************* */
// Этот модуль содержит функции для написания юнит-тестов для вашей программы. Для их использования сделайте импорт require('assert').
assert.fail(actual, expected, message, operator); // Выбрасывает исключение, которое отображает актуально и ожидаемое значения, разделенные переданным оператором
assert(value, message); и assert.ok(value, [message]); // Проверят значение на истину. Является эквивалентом функции assert.equal(true, !!value, message);
assert.equal(actual, expected, [message]); // Сравнивает 2 значения с помощью оператора нестрогого равенства ( == ).
assert.notEqual(actual, expected, [message]); // Сравнивает 2 значения с помощью оператора нестрогого неравенства ( != ).
assert.deepEqual(actual, expected, [message]); // Производит глубокую проверку равенства.
assert.notDeepEqual(actual, expected, [message]); // Производит глубокую проверку неравенства.
assert.strictEqual(actual, expected, [message]); // Сравнивает 2 значения с помощью оператора строгого равенства ( === ).
assert.notStrictEqual(actual, expected, [message]); // Сравнивает 2 значения с помощью оператора строгого неравенства ( !== )
assert.throws(block, [error], [message]); // Ожидает, что блок кода выбросит исключение error. error может быть функцией-конструктором, RegExp или функцией валидации значений.
assert.doesNotThrow(block, [message]); // Ожидает, что блок кода не выбросит исключение error. error может быть функцией-конструктором, RegExp или функцией валидации значений.
assert.ifError(value); // Проверяет, что значение не равно false. Выбрасывает исключение, если оно равно true. Полезно для использования, когда первый аргумент является error в функции callbacks.
/* *******************************************************************************************
* Операционная система
* http://nodejs.org/api/os.html
* ******************************************************************************************* */
// Модуль предоставляет функции для получения информации об операционной системе.
// Для их использования сделайте импорт require('os').
os.tmpdir(); // Возвращает путь до директории temp.
os.endianness(); // Возвращает порядок байт процессора. Возможные значения "BE" или "LE".
os.hostname(); // Возвращает имя компьютера.
os.type(); // Возвращает название операционной системы.
os.platform(); // Возвращает вид операционной системы.
os.arch(); // Возвращает тип архитектуры процессора.
os.release(); // Возвращает версию операционной системы.
os.uptime(); // Возвравщает время работы операционной системы в секундах.
os.loadavg(); // Возвращает массив, содержащий 1, 5, и 15 минутные значения средней нагрузки.
os.totalmem(); // Возвращает общее число байт имеющейся оперативной памяти в системе.
os.freemem(); // Возвращает число байт свободной оперативной памяти в системе.
os.cpus(); // Возвращает массив с объектами, содержащими информацию по каждому ядру или процессору, установленному в системе: модель, скорость в мегагерцах и время (объект, содержащий время потраченное ядром процессора на: user, nice, sys, idle, and irq).
os.networkInterfaces(); // Возвращает список доступных сетевых интерфейсов.
os.EOL; // Константа, в которой содержится маркер конца строки для данной операционной системы. Например: \r\n.
/* *******************************************************************************************
* BUFFER
* http://nodejs.org/api/buffer.html
* ******************************************************************************************* */
// Buffer используется для обработки двоичных данных.
// Buffer похож на массив с числами, но он относится к сырой памяти, расположенной вне кучи V8.
Buffer.from(size); // Создает новый буфер с заданным числом октетов.
Buffer.from(array); // Создает новый буфер из массива октетов.
Buffer.from(str, [encoding]); // Создает новый буфер из строки с заданной кодировкой. По умолчанию задана кодировка 'utf8'.
Buffer.isEncoding(encoding); // Возвращает true, если кодировка для буфера допустима и false, если недопустима.
Buffer.isBuffer(obj); // Проверяет является ли объекто буффером.
Buffer.concat(list, [totalLength]); // Объединяет несколько буферов в один.
Buffer.byteLength(string, [encoding]); // Возвращает дину строки в байтах.
buf.write(string, [offset], [length], [encoding]); // Записывает строку в буфер с учетом смещения и заданной кодировки.
buf.toString([encoding], [start], [end]); // Преобразует буфер в строку с учетом кодировки (по умолчанию задана кодировка 'utf8') и начала (по умолчанию задано 0) и конца буфера (по умолчанию равно buffer.length).
buf.toJSON(); // Преобразует буфер в формат JSON.
buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd]); // Копирует значения из одного буфера в другой буфер. Исходная и целевая области буфера могут перекрываться.
buf.slice([start], [end]); // Возвращает новый буфер, в который ссылается на ту же область памяти, что и старый, но со смещением offset и обрезанием от стартового start (по умолчанию равно 0) до конечного end индекса (по умолчанию равно buffer.length). Отрицательные индексы допустимы.
buf.fill(value, [offset], [end]); // Заполняет этот буфер заданными значениями. Если в буфере есть значения, то они заменяются заданными.
buf[index]; // Получить и установить октет буфера с данным индексом.
buf.length; // Размер буфера в байтах. The size of the buffer in bytes, Обратите внимание, что это не обязательно размер содержимого.
buffer.INSPECT_MAX_BYTES; // Сколько байт максимально может быть возвращено функцией buffer.inspect(). Это значение может быть перезаписано пользователем данного модуля.
среда, 25 апреля 2018 г.
Node.js - Proxy Server
Файл index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Proxy Server</title>
</head>
<body>
<form method="GET" action="proxy">
<input name="proxyreq" type="text" value="http://127.0.0.2:80/" />
<input type="submit" value="Показать" />
</form>
</body>
</html>
Файл proxy.js (загружает также картинку favicon.png)
var http = require('http')
, url = require('url')
, querystring = require('querystring')
, path = require('path')
, fs = require('fs')
, replaceHTML = require('./replaceHTML')
, replaceCSS = require('./replaceCSS')
, replaceJavaScript = require('./replaceJavaScript');
var proxyHost = '127.0.0.1'
, proxyPort = 80;
var proxyServer = http.createServer();
proxyServer.on('request', function (proxyRequest, proxyResponse) {
var reqUrl = url.parse(proxyRequest.url)
, pathname = reqUrl.pathname;
if (pathname === '/' || pathname === 'index.html') {
fs.readFile(path.resolve(path.join(__dirname, 'index.html')), function (error, data) {
if (error) {throw error;}
proxyResponse.writeHead(200, 'OK', {'Content-Type': 'text/html'});
proxyResponse.write(data);
proxyResponse.end();
});
} else if (pathname === '/favicon.ico') {
fs.readFile('./favicon.png', function (error, data) {
if (error) {throw error;}
response.writeHead(200, 'OK', {'Content-Type': 'image/png', 'Content-Length': Buffer.byteLength(data)});
response.write(data);
response.end();
});
} else if (pathname.indexOf('/proxyform/') === 0) {
var proxyreq = pathname.slice('/proxyform/'.length);
proxyreq = querystring.unescape(proxyreq);
proxyreq = path.posix.normalize(proxyreq);
proxyreq = proxyreq.replace('http:/', 'http://');
var proxyUrl = url.parse(proxyreq);
var requestOptions = {
method: proxyRequest.method
, protocol: proxyUrl.protocol
, hostname: proxyUrl.hostname
, port: proxyUrl.port
, path: proxyUrl.pathname + (proxyRequest.method === 'GET' ? url.parse(proxyRequest.url).search : '')
, headers: proxyRequest.headers
};
var requestToOutterServer = http.request(requestOptions);
requestToOutterServer.on('response', function (outterServerResponse) {
var outterServerResponseData = [];
outterServerResponse.on('data', function (chunk) {outterServerResponseData.push(chunk);});
outterServerResponse.on('end', function () {
if (outterServerResponse.headers['content-type'] === 'text/html') {
outterServerResponseData = replaceHTML(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else if (outterServerResponse.headers['content-type'] === 'text/css') {
outterServerResponseData = replaceCSS(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
, path.parse(proxyUrl.pathname).dir
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else if (outterServerResponse.headers['content-type'] === 'text/javascript') {
outterServerResponseData = replaceJavaScript(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else {
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
outterServerResponseData.forEach(function (chunk) {
proxyResponse.write(chunk);
});
proxyResponse.end();
}
});
});
requestToOutterServer.on('error', function (error) {
console.log(requestOptions);
/*
console.error(error);
proxyResponse.writeHead(500, 'Internal Server Error', {'Content-Type': 'text/html'});
proxyResponse.write('500 Internal Server Error');
proxyResponse.end();
*/
throw error;
});
if (proxyRequest.method === 'GET') {
requestToOutterServer.end();
} else if (proxyRequest.method === 'POST') {
proxyRequest.on('data', function (chunk) {requestToOutterServer.write(chunk);});
proxyRequest.on('end', function () {requestToOutterServer.end();});
}
} else if (pathname.indexOf('/proxy') === 0) {
if (reqUrl.search) {
var searchData = reqUrl.search.slice(1);
searchData = querystring.parse(searchData);
var proxyreq = searchData.proxyreq;
proxyreq = querystring.unescape(proxyreq);
proxyreq = path.posix.normalize(proxyreq);
proxyreq = proxyreq.replace('http:/', 'http://');
var proxyUrl = url.parse(proxyreq);
delete searchData.proxyreq;
var requestOptions = {
method: proxyRequest.method
, protocol: proxyUrl.protocol
, hostname: proxyUrl.hostname
, port: proxyUrl.port
, path: proxyUrl.pathname + (proxyRequest.method === 'GET' ? querystring.stringify(searchData) : '')
, headers: proxyRequest.headers
};
var requestToOutterServer = http.request(requestOptions);
requestToOutterServer.on('response', function (outterServerResponse) {
var outterServerResponseData = [];
outterServerResponse.on('data', function (chunk) {outterServerResponseData.push(chunk);});
outterServerResponse.on('end', function () {
if (outterServerResponse.headers['content-type'] === 'text/html') {
outterServerResponseData = replaceHTML(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else if (outterServerResponse.headers['content-type'] === 'text/css') {
outterServerResponseData = replaceCSS(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
, path.parse(proxyUrl.pathname).dir
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else if (outterServerResponse.headers['content-type'] === 'text/javascript') {
outterServerResponseData = replaceJavaScript(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else {
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
outterServerResponseData.forEach(function (chunk) {
proxyResponse.write(chunk);
});
proxyResponse.end();
}
});
});
requestToOutterServer.on('error', function (error) {
console.log(requestOptions);
/*
console.error(error);
proxyResponse.writeHead(500, 'Internal Server Error', {'Content-Type': 'text/html'});
proxyResponse.write('500 Internal Server Error');
proxyResponse.end();
*/
throw error;
});
if (proxyRequest.method === 'GET') {
requestToOutterServer.end();
} else if (proxyRequest.method === 'POST') {
proxyRequest.on('data', function (chunk) {requestToOutterServer.write(chunk);});
proxyRequest.on('end', function () {requestToOutterServer.end();});
}
} else {
proxyResponse.writeHead(200, 'OK', {'Content-Type': 'text/html'});
proxyResponse.write('<p>Адрес не задан.</p>');
proxyResponse.write('<a href="/">Вернуться на страницу ввода адреса.</a>');
proxyResponse.end();
}
} else {
proxyResponse.writeHead(404, 'Not Found', {'Content-Type': 'text/html'});
proxyResponse.write('404 Not Found');
proxyResponse.end();
}
});
proxyServer.on('error', function (error) {throw error;});
proxyServer.listen(proxyPort, proxyHost, function () {
console.log('Proxy server started at ' + proxyHost + ':' + proxyPort);
});
Файл replaceHTML.js
var querystring = require('querystring');
function replacePath (htmlString, regexp, proxyServerAddress, outterServerAddress) {
return htmlString.replace(regexp, function (match, $1, $2, $3) {
var newPath;
if ($2.indexOf('http') === 0) {
newPath = proxyServerAddress + querystring.escape($2);
} else if ($2.indexOf('/') === 0) {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + $2);
} else {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + '/' + $2);
}
return $1 + newPath + $3;
});
}
function replaceHref (htmlString, proxyServerAddress, outterServerAddress) {
return replacePath(htmlString, /(href=")([^"]+)(")/gi, proxyServerAddress, outterServerAddress)
}
/*
console.log(replaceHref([
'<link href="style1.css" rel="stylesheet" type="text/css" />'
, '<link href="/style2.css" rel="stylesheet" type="text/css" />'
, '<link href="http://www.google.com/style3.css" rel="stylesheet" type="text/css" />'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceSrc (htmlString, proxyServerAddress, outterServerAddress) {
return replacePath(htmlString, /(src=")([^"]+)(")/gi, proxyServerAddress, outterServerAddress)
}
/*
console.log(replaceSrc([
'<img src="image1.png" />'
, '<img src="/image2.png" />'
, '<img src="http://www.google.com/image3.png" />'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceAction (htmlString, proxyServerAddress, outterServerAddress) {
proxyServerAddress = proxyServerAddress.replace('/proxy/?proxyreq=', '/proxyform/');
return htmlString.replace(/(action=")([^"]+)(")/gi, function (match, $1, $2, $3) {
var newPath;
if ($2.indexOf('http') === 0) {
newPath = proxyServerAddress + querystring.escape($2);
} else if ($2.indexOf('/') === 0) {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + $2);
} else {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + '/' + $2);
}
return $1 + newPath + $3;
});
// return replacePath(htmlString, /(action=")([^"]+)(")/gi, proxyServerAddress, outterServerAddress)
}
/*
console.log(replaceAction([
'<form action="submit" method="GET"><input name= "a" type="texy" value="1" /><input type="submit" value="Submit 1" /></form>'
, '<form action="/submit" method="GET"><input name= "b" type="texy" value="2" /><input type="submit" value="Submit 2" /></form>'
, '<form action="http://127.0.0.2:80/submit" method="GET"><input name= "c" type="texy" value="3" /><input type="submit" value="Submit 3" /></form>'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceData (htmlString, proxyServerAddress, outterServerAddress) {
return replacePath(htmlString, /(data=")([^"]+)(")/gi, proxyServerAddress, outterServerAddress)
}
/*
console.log(replaceData([
'<object data="video.mp4" />'
, '<object data="/video.mp4" />'
, '<object data="http://www.google.com/video.mp4" />'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceXMLHttpRequest (htmlString, proxyServerAddress, outterServerAddress) {
return htmlString.replace(/<head>/gi, function () {
return '<head>' + [
'<script type="text/javascript">'
+ ';(function (open) {'
+ 'window.XMLHttpRequest.prototype.open = function (method, url, async) {'
+ 'var newUrl;'
+ 'if (url.indexOf("http") === 0) {'
+ 'newUrl = "' + proxyServerAddress + '" + window.encodeURIComponent(url);'
+ '} else if (url.indexOf("/") === 0) {'
+ 'newUrl = "' + proxyServerAddress + '" + window.encodeURIComponent("' + outterServerAddress + '" + url);'
+ '} else {'
+ 'newUrl = "' + proxyServerAddress + '" + window.encodeURIComponent("' + outterServerAddress + '" + "/" + url);'
+ '}'
+ 'open.call(this, method, newUrl, async);'
+ '};'
+ '})(window.XMLHttpRequest.prototype.open);'
+ '</script>'
].join('');
});
}
/*
console.log(replaceXMLHttpRequest([
'<!DOCTYPE html>'
+ '<html>'
+ '<head>'
+ '<link href="favicon.png" rel="icon" type="image/png" />'
+ '<link href="static/css/style1.css" rel="stylesheet" type="text/css" />'
+ '<link href="/static/css/style2.css" rel="stylesheet" type="text/css" />'
+ '<link href="http://127.0.0.2:80/static/css/style3.css" rel="stylesheet" type="text/css" />'
+ '<script src="static/js/script1.js"></script>'
+ '<script src="/static/js/script2.js"></script>'
+ '<script src="http://127.0.0.2:80/static/js/script3.js"></script>'
+ '<meta charset="utf-8" />'
+ '<title>Test page</title>'
+ '</head>'
].join('\n'), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
module.exports = function replaceHTML (htmlString, proxyServerAddress, outterServerAddress) {
htmlString = replaceHref(htmlString, proxyServerAddress, outterServerAddress);
htmlString = replaceSrc(htmlString, proxyServerAddress, outterServerAddress);
htmlString = replaceAction(htmlString, proxyServerAddress, outterServerAddress);
htmlString = replaceData(htmlString, proxyServerAddress, outterServerAddress);
htmlString = replaceXMLHttpRequest(htmlString, proxyServerAddress, outterServerAddress);
return htmlString;
};
Файл replaceCSS.js
function replaceUrl (cssString, proxyServerAddress, outterServerAddress, rootPath) {
return cssString.replace(/url\([^\)]+\)/gi, function (match) {
match = match.replace(/url\(/gi, '');
match = match.replace(/\)/gi, '');
match = match.replace(/"/gi, '');
match = match.replace(/'/gi, '');
match = match.replace(/^\s+/, '');
match = match.replace(/\s+$/, '');
if (!(match.indexOf('/') === 0 || match.indexOf('http') === 0)) {
match = joinPaths(rootPath, match);
}
var newPath;
if (match.indexOf('http') === 0) {
newPath = proxyServerAddress + match;
} else if (match.indexOf('/') === 0) {
newPath = proxyServerAddress + outterServerAddress + match;
} else {
newPath = proxyServerAddress + outterServerAddress + '/' + match;
}
return 'url("' + newPath + '")';
});
}
function joinPaths (root, path) {
if (path.indexOf('../') === 0) {
if (root.indexOf('/') === root.lastIndexOf('/')) {
if (root[root.length - 1] === '/') {root = root.slice(0, root.length - 1);}
if (path[0] === '/') {path = path.slice(1);}
return root + '/' + path;
} else {
path = path.slice(3);
root = root.slice(0, root.lastIndexOf('/'));
return joinPaths(root, path);
}
} else {
if (root[root.length - 1] === '/') {root = root.slice(0, root.length - 1);}
if (path[0] === '/') {path = path.slice(1);}
return root + '/' + path;
}
}
/*
console.log(replaceUrl([
'body {background: url(image.png) repeat-x repeat-y;}'
, 'div {background: url(/image.png) repeat-x repeat-y;}'
, 'p {background: url(http://www.google.com/image.png) repeat-x repeat-y;}'
, 'body {background: url("image.png") repeat-x repeat-y;}'
, 'div {background: url("/image.png") repeat-x repeat-y;}'
, 'p {background: url("http://www.google.com/image.png") repeat-x repeat-y;}'
, '@import url(\'style2.css\');'
, '@import url("/style2.css");'
, '@import url("http://www.google.com/style2.css");'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
module.exports = function replaceCSS (cssString, proxyServerAddress, outterServerAddress, rootPath) {
cssString = replaceUrl(cssString, proxyServerAddress, outterServerAddress, rootPath);
return cssString;
};
Файл replaceJavaScript.js
var querystring = require('querystring');
function replacePath (javascriptString, regexp, proxyServerAddress, outterServerAddress) {
return javascriptString.replace(regexp, function (match, $1, $2, $3, $4) {
var newPath;
if ($3.indexOf('http') === 0) {
newPath = proxyServerAddress + querystring.escape($3);
} else if ($3.indexOf('/') === 0) {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + $3);
} else {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + '/' + $3);
}
return $1 + $2 + newPath + $4;
});
}
function replaceVarPath (javascriptString, regexp, proxyServerAddress, outterServerAddress) {
return javascriptString.replace(regexp, function (match, $1, $2) {
return $1 + '"' + proxyServerAddress + querystring.escape(outterServerAddress) + '/" + ' + $2;
});
}
function replaceVarSrc (javascriptString, proxyServerAddress, outterServerAddress) {
return replaceVarPath(javascriptString, /(\.\s*src\s*=\s*)([a-zA-Z$_]+)/gi, proxyServerAddress, outterServerAddress);
}
/*
console.log(replaceVarSrc([
'img . src = someVar'
, 'img.src = someVar + "/path"'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceSrc (javascriptString, proxyServerAddress, outterServerAddress) {
return replacePath(javascriptString, /(\.\s*src\s*=\s*)('|")([^'"]+)('|")/gi, proxyServerAddress, outterServerAddress);
}
/*
console.log(replaceSrc([
'img . src = \'path\''
, 'img.src = "/path"'
, 'img.src="http://www.google.com/path"'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceHref (javascriptString, proxyServerAddress, outterServerAddress) {
return replacePath(javascriptString, /(\.\s*href\s*=\s*)('|")([^'"]+)('|")/gi, proxyServerAddress, outterServerAddress);
}
/*
console.log(replaceHref([
'location . href = \'path\''
, 'location.href = "/path"'
, 'location.href="http://www.google.com/path"'
, 'a . href = \'path\''
, 'a.href = "/path"'
, 'a.href="http://www.google.com/path"'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceVarHref (javascriptString, proxyServerAddress, outterServerAddress) {
return replaceVarPath(javascriptString, /(\.\s*href\s*=\s*)([a-zA-Z$_]+)/gi, proxyServerAddress, outterServerAddress);
}
/*
console.log(replaceVarSrc([
'img . href = someVar'
, 'img.href = someVar + "/path"'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
module.exports = function replaceJavaScript (javascriptString, proxyServerAddress, outterServerAddress) {
javascriptString = replaceSrc(javascriptString, proxyServerAddress, outterServerAddress);
javascriptString = replaceVarSrc(javascriptString, proxyServerAddress, outterServerAddress);
javascriptString = replaceHref(javascriptString, proxyServerAddress, outterServerAddress);
javascriptString = replaceVarHref(javascriptString, proxyServerAddress, outterServerAddress);
return javascriptString;
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Proxy Server</title>
</head>
<body>
<form method="GET" action="proxy">
<input name="proxyreq" type="text" value="http://127.0.0.2:80/" />
<input type="submit" value="Показать" />
</form>
</body>
</html>
Файл proxy.js (загружает также картинку favicon.png)
var http = require('http')
, url = require('url')
, querystring = require('querystring')
, path = require('path')
, fs = require('fs')
, replaceHTML = require('./replaceHTML')
, replaceCSS = require('./replaceCSS')
, replaceJavaScript = require('./replaceJavaScript');
var proxyHost = '127.0.0.1'
, proxyPort = 80;
var proxyServer = http.createServer();
proxyServer.on('request', function (proxyRequest, proxyResponse) {
var reqUrl = url.parse(proxyRequest.url)
, pathname = reqUrl.pathname;
if (pathname === '/' || pathname === 'index.html') {
fs.readFile(path.resolve(path.join(__dirname, 'index.html')), function (error, data) {
if (error) {throw error;}
proxyResponse.writeHead(200, 'OK', {'Content-Type': 'text/html'});
proxyResponse.write(data);
proxyResponse.end();
});
} else if (pathname === '/favicon.ico') {
fs.readFile('./favicon.png', function (error, data) {
if (error) {throw error;}
response.writeHead(200, 'OK', {'Content-Type': 'image/png', 'Content-Length': Buffer.byteLength(data)});
response.write(data);
response.end();
});
} else if (pathname.indexOf('/proxyform/') === 0) {
var proxyreq = pathname.slice('/proxyform/'.length);
proxyreq = querystring.unescape(proxyreq);
proxyreq = path.posix.normalize(proxyreq);
proxyreq = proxyreq.replace('http:/', 'http://');
var proxyUrl = url.parse(proxyreq);
var requestOptions = {
method: proxyRequest.method
, protocol: proxyUrl.protocol
, hostname: proxyUrl.hostname
, port: proxyUrl.port
, path: proxyUrl.pathname + (proxyRequest.method === 'GET' ? url.parse(proxyRequest.url).search : '')
, headers: proxyRequest.headers
};
var requestToOutterServer = http.request(requestOptions);
requestToOutterServer.on('response', function (outterServerResponse) {
var outterServerResponseData = [];
outterServerResponse.on('data', function (chunk) {outterServerResponseData.push(chunk);});
outterServerResponse.on('end', function () {
if (outterServerResponse.headers['content-type'] === 'text/html') {
outterServerResponseData = replaceHTML(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else if (outterServerResponse.headers['content-type'] === 'text/css') {
outterServerResponseData = replaceCSS(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
, path.parse(proxyUrl.pathname).dir
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else if (outterServerResponse.headers['content-type'] === 'text/javascript') {
outterServerResponseData = replaceJavaScript(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else {
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
outterServerResponseData.forEach(function (chunk) {
proxyResponse.write(chunk);
});
proxyResponse.end();
}
});
});
requestToOutterServer.on('error', function (error) {
console.log(requestOptions);
/*
console.error(error);
proxyResponse.writeHead(500, 'Internal Server Error', {'Content-Type': 'text/html'});
proxyResponse.write('500 Internal Server Error');
proxyResponse.end();
*/
throw error;
});
if (proxyRequest.method === 'GET') {
requestToOutterServer.end();
} else if (proxyRequest.method === 'POST') {
proxyRequest.on('data', function (chunk) {requestToOutterServer.write(chunk);});
proxyRequest.on('end', function () {requestToOutterServer.end();});
}
} else if (pathname.indexOf('/proxy') === 0) {
if (reqUrl.search) {
var searchData = reqUrl.search.slice(1);
searchData = querystring.parse(searchData);
var proxyreq = searchData.proxyreq;
proxyreq = querystring.unescape(proxyreq);
proxyreq = path.posix.normalize(proxyreq);
proxyreq = proxyreq.replace('http:/', 'http://');
var proxyUrl = url.parse(proxyreq);
delete searchData.proxyreq;
var requestOptions = {
method: proxyRequest.method
, protocol: proxyUrl.protocol
, hostname: proxyUrl.hostname
, port: proxyUrl.port
, path: proxyUrl.pathname + (proxyRequest.method === 'GET' ? querystring.stringify(searchData) : '')
, headers: proxyRequest.headers
};
var requestToOutterServer = http.request(requestOptions);
requestToOutterServer.on('response', function (outterServerResponse) {
var outterServerResponseData = [];
outterServerResponse.on('data', function (chunk) {outterServerResponseData.push(chunk);});
outterServerResponse.on('end', function () {
if (outterServerResponse.headers['content-type'] === 'text/html') {
outterServerResponseData = replaceHTML(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else if (outterServerResponse.headers['content-type'] === 'text/css') {
outterServerResponseData = replaceCSS(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
, path.parse(proxyUrl.pathname).dir
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else if (outterServerResponse.headers['content-type'] === 'text/javascript') {
outterServerResponseData = replaceJavaScript(
outterServerResponseData.join('')
, 'http://' + proxyHost + ':' + proxyPort + '/proxy/?proxyreq='
, proxyUrl.protocol + '//' + proxyUrl.hostname + ':' + proxyUrl.port
);
outterServerResponse.headers['content-length'] = Buffer.byteLength(outterServerResponseData);
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
proxyResponse.end(outterServerResponseData);
} else {
proxyResponse.writeHead(outterServerResponse.statusCode, outterServerResponse.statusMessage, outterServerResponse.headers);
outterServerResponseData.forEach(function (chunk) {
proxyResponse.write(chunk);
});
proxyResponse.end();
}
});
});
requestToOutterServer.on('error', function (error) {
console.log(requestOptions);
/*
console.error(error);
proxyResponse.writeHead(500, 'Internal Server Error', {'Content-Type': 'text/html'});
proxyResponse.write('500 Internal Server Error');
proxyResponse.end();
*/
throw error;
});
if (proxyRequest.method === 'GET') {
requestToOutterServer.end();
} else if (proxyRequest.method === 'POST') {
proxyRequest.on('data', function (chunk) {requestToOutterServer.write(chunk);});
proxyRequest.on('end', function () {requestToOutterServer.end();});
}
} else {
proxyResponse.writeHead(200, 'OK', {'Content-Type': 'text/html'});
proxyResponse.write('<p>Адрес не задан.</p>');
proxyResponse.write('<a href="/">Вернуться на страницу ввода адреса.</a>');
proxyResponse.end();
}
} else {
proxyResponse.writeHead(404, 'Not Found', {'Content-Type': 'text/html'});
proxyResponse.write('404 Not Found');
proxyResponse.end();
}
});
proxyServer.on('error', function (error) {throw error;});
proxyServer.listen(proxyPort, proxyHost, function () {
console.log('Proxy server started at ' + proxyHost + ':' + proxyPort);
});
Файл replaceHTML.js
var querystring = require('querystring');
function replacePath (htmlString, regexp, proxyServerAddress, outterServerAddress) {
return htmlString.replace(regexp, function (match, $1, $2, $3) {
var newPath;
if ($2.indexOf('http') === 0) {
newPath = proxyServerAddress + querystring.escape($2);
} else if ($2.indexOf('/') === 0) {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + $2);
} else {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + '/' + $2);
}
return $1 + newPath + $3;
});
}
function replaceHref (htmlString, proxyServerAddress, outterServerAddress) {
return replacePath(htmlString, /(href=")([^"]+)(")/gi, proxyServerAddress, outterServerAddress)
}
/*
console.log(replaceHref([
'<link href="style1.css" rel="stylesheet" type="text/css" />'
, '<link href="/style2.css" rel="stylesheet" type="text/css" />'
, '<link href="http://www.google.com/style3.css" rel="stylesheet" type="text/css" />'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceSrc (htmlString, proxyServerAddress, outterServerAddress) {
return replacePath(htmlString, /(src=")([^"]+)(")/gi, proxyServerAddress, outterServerAddress)
}
/*
console.log(replaceSrc([
'<img src="image1.png" />'
, '<img src="/image2.png" />'
, '<img src="http://www.google.com/image3.png" />'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceAction (htmlString, proxyServerAddress, outterServerAddress) {
proxyServerAddress = proxyServerAddress.replace('/proxy/?proxyreq=', '/proxyform/');
return htmlString.replace(/(action=")([^"]+)(")/gi, function (match, $1, $2, $3) {
var newPath;
if ($2.indexOf('http') === 0) {
newPath = proxyServerAddress + querystring.escape($2);
} else if ($2.indexOf('/') === 0) {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + $2);
} else {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + '/' + $2);
}
return $1 + newPath + $3;
});
// return replacePath(htmlString, /(action=")([^"]+)(")/gi, proxyServerAddress, outterServerAddress)
}
/*
console.log(replaceAction([
'<form action="submit" method="GET"><input name= "a" type="texy" value="1" /><input type="submit" value="Submit 1" /></form>'
, '<form action="/submit" method="GET"><input name= "b" type="texy" value="2" /><input type="submit" value="Submit 2" /></form>'
, '<form action="http://127.0.0.2:80/submit" method="GET"><input name= "c" type="texy" value="3" /><input type="submit" value="Submit 3" /></form>'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceData (htmlString, proxyServerAddress, outterServerAddress) {
return replacePath(htmlString, /(data=")([^"]+)(")/gi, proxyServerAddress, outterServerAddress)
}
/*
console.log(replaceData([
'<object data="video.mp4" />'
, '<object data="/video.mp4" />'
, '<object data="http://www.google.com/video.mp4" />'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceXMLHttpRequest (htmlString, proxyServerAddress, outterServerAddress) {
return htmlString.replace(/<head>/gi, function () {
return '<head>' + [
'<script type="text/javascript">'
+ ';(function (open) {'
+ 'window.XMLHttpRequest.prototype.open = function (method, url, async) {'
+ 'var newUrl;'
+ 'if (url.indexOf("http") === 0) {'
+ 'newUrl = "' + proxyServerAddress + '" + window.encodeURIComponent(url);'
+ '} else if (url.indexOf("/") === 0) {'
+ 'newUrl = "' + proxyServerAddress + '" + window.encodeURIComponent("' + outterServerAddress + '" + url);'
+ '} else {'
+ 'newUrl = "' + proxyServerAddress + '" + window.encodeURIComponent("' + outterServerAddress + '" + "/" + url);'
+ '}'
+ 'open.call(this, method, newUrl, async);'
+ '};'
+ '})(window.XMLHttpRequest.prototype.open);'
+ '</script>'
].join('');
});
}
/*
console.log(replaceXMLHttpRequest([
'<!DOCTYPE html>'
+ '<html>'
+ '<head>'
+ '<link href="favicon.png" rel="icon" type="image/png" />'
+ '<link href="static/css/style1.css" rel="stylesheet" type="text/css" />'
+ '<link href="/static/css/style2.css" rel="stylesheet" type="text/css" />'
+ '<link href="http://127.0.0.2:80/static/css/style3.css" rel="stylesheet" type="text/css" />'
+ '<script src="static/js/script1.js"></script>'
+ '<script src="/static/js/script2.js"></script>'
+ '<script src="http://127.0.0.2:80/static/js/script3.js"></script>'
+ '<meta charset="utf-8" />'
+ '<title>Test page</title>'
+ '</head>'
].join('\n'), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
module.exports = function replaceHTML (htmlString, proxyServerAddress, outterServerAddress) {
htmlString = replaceHref(htmlString, proxyServerAddress, outterServerAddress);
htmlString = replaceSrc(htmlString, proxyServerAddress, outterServerAddress);
htmlString = replaceAction(htmlString, proxyServerAddress, outterServerAddress);
htmlString = replaceData(htmlString, proxyServerAddress, outterServerAddress);
htmlString = replaceXMLHttpRequest(htmlString, proxyServerAddress, outterServerAddress);
return htmlString;
};
Файл replaceCSS.js
function replaceUrl (cssString, proxyServerAddress, outterServerAddress, rootPath) {
return cssString.replace(/url\([^\)]+\)/gi, function (match) {
match = match.replace(/url\(/gi, '');
match = match.replace(/\)/gi, '');
match = match.replace(/"/gi, '');
match = match.replace(/'/gi, '');
match = match.replace(/^\s+/, '');
match = match.replace(/\s+$/, '');
if (!(match.indexOf('/') === 0 || match.indexOf('http') === 0)) {
match = joinPaths(rootPath, match);
}
var newPath;
if (match.indexOf('http') === 0) {
newPath = proxyServerAddress + match;
} else if (match.indexOf('/') === 0) {
newPath = proxyServerAddress + outterServerAddress + match;
} else {
newPath = proxyServerAddress + outterServerAddress + '/' + match;
}
return 'url("' + newPath + '")';
});
}
function joinPaths (root, path) {
if (path.indexOf('../') === 0) {
if (root.indexOf('/') === root.lastIndexOf('/')) {
if (root[root.length - 1] === '/') {root = root.slice(0, root.length - 1);}
if (path[0] === '/') {path = path.slice(1);}
return root + '/' + path;
} else {
path = path.slice(3);
root = root.slice(0, root.lastIndexOf('/'));
return joinPaths(root, path);
}
} else {
if (root[root.length - 1] === '/') {root = root.slice(0, root.length - 1);}
if (path[0] === '/') {path = path.slice(1);}
return root + '/' + path;
}
}
/*
console.log(replaceUrl([
'body {background: url(image.png) repeat-x repeat-y;}'
, 'div {background: url(/image.png) repeat-x repeat-y;}'
, 'p {background: url(http://www.google.com/image.png) repeat-x repeat-y;}'
, 'body {background: url("image.png") repeat-x repeat-y;}'
, 'div {background: url("/image.png") repeat-x repeat-y;}'
, 'p {background: url("http://www.google.com/image.png") repeat-x repeat-y;}'
, '@import url(\'style2.css\');'
, '@import url("/style2.css");'
, '@import url("http://www.google.com/style2.css");'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
module.exports = function replaceCSS (cssString, proxyServerAddress, outterServerAddress, rootPath) {
cssString = replaceUrl(cssString, proxyServerAddress, outterServerAddress, rootPath);
return cssString;
};
Файл replaceJavaScript.js
var querystring = require('querystring');
function replacePath (javascriptString, regexp, proxyServerAddress, outterServerAddress) {
return javascriptString.replace(regexp, function (match, $1, $2, $3, $4) {
var newPath;
if ($3.indexOf('http') === 0) {
newPath = proxyServerAddress + querystring.escape($3);
} else if ($3.indexOf('/') === 0) {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + $3);
} else {
newPath = proxyServerAddress + querystring.escape(outterServerAddress + '/' + $3);
}
return $1 + $2 + newPath + $4;
});
}
function replaceVarPath (javascriptString, regexp, proxyServerAddress, outterServerAddress) {
return javascriptString.replace(regexp, function (match, $1, $2) {
return $1 + '"' + proxyServerAddress + querystring.escape(outterServerAddress) + '/" + ' + $2;
});
}
function replaceVarSrc (javascriptString, proxyServerAddress, outterServerAddress) {
return replaceVarPath(javascriptString, /(\.\s*src\s*=\s*)([a-zA-Z$_]+)/gi, proxyServerAddress, outterServerAddress);
}
/*
console.log(replaceVarSrc([
'img . src = someVar'
, 'img.src = someVar + "/path"'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceSrc (javascriptString, proxyServerAddress, outterServerAddress) {
return replacePath(javascriptString, /(\.\s*src\s*=\s*)('|")([^'"]+)('|")/gi, proxyServerAddress, outterServerAddress);
}
/*
console.log(replaceSrc([
'img . src = \'path\''
, 'img.src = "/path"'
, 'img.src="http://www.google.com/path"'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceHref (javascriptString, proxyServerAddress, outterServerAddress) {
return replacePath(javascriptString, /(\.\s*href\s*=\s*)('|")([^'"]+)('|")/gi, proxyServerAddress, outterServerAddress);
}
/*
console.log(replaceHref([
'location . href = \'path\''
, 'location.href = "/path"'
, 'location.href="http://www.google.com/path"'
, 'a . href = \'path\''
, 'a.href = "/path"'
, 'a.href="http://www.google.com/path"'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
function replaceVarHref (javascriptString, proxyServerAddress, outterServerAddress) {
return replaceVarPath(javascriptString, /(\.\s*href\s*=\s*)([a-zA-Z$_]+)/gi, proxyServerAddress, outterServerAddress);
}
/*
console.log(replaceVarSrc([
'img . href = someVar'
, 'img.href = someVar + "/path"'
].join(' | '), 'http://127.0.0.1:80/?proxyreq=', 'http://127.0.0.2:80'));
*/
module.exports = function replaceJavaScript (javascriptString, proxyServerAddress, outterServerAddress) {
javascriptString = replaceSrc(javascriptString, proxyServerAddress, outterServerAddress);
javascriptString = replaceVarSrc(javascriptString, proxyServerAddress, outterServerAddress);
javascriptString = replaceHref(javascriptString, proxyServerAddress, outterServerAddress);
javascriptString = replaceVarHref(javascriptString, proxyServerAddress, outterServerAddress);
return javascriptString;
};
Подписаться на:
Сообщения (Atom)