Ответы пользователя по тегу Node.js
  • Как исправить ошибку при подключении библиотеки в node js npm?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Установите python а затем попробуйте еще раз

    ЗЫ: иногда очень полезно читать то, что выводится в консоль, особенно, если там написано что надо делать, чтобы исправить ошибку.
    5f2c93e8811fb705169945.png
    Ответ написан
  • Как перегнать буфер в строку?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    если кодировка строки, лежащей в буфере UTF-8 или UTF-16 то
    так Buffer.toString
    или так String decoder

    есликонсоль не поддерживает utf то для вывода можно использовать Buffer.transcode
    Ответ написан
  • Как сохранить файл отправленный в сообщении?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Как то так:
    const fs = require("fs");
    const Discord = require("discord.js");
    const client = new Discord.Client();
    
    client.login("ТУТ ВАШ ТОКЕН");
    
    ...
    
    // обработчик события message
    client.on('message', async message => {
    
        const filename = Date.now()+".json";
        const data = {
            content: message.content,
            attachments: message.attachments.map(attach=>{
                return {
                    id: attach.id,
                    url: attach.url,
                    proxyURL: attach.proxyURL,
                    filename: attach.filename,
                    filesize: attach.filesize,
                    height: attach.height,
                    width: attach.width
                };
            })
        };
    
        // не забудьте создать папочку logs в папке с ботом
        fs.writeFile('./logs/'+filename, JSON.stringify(data), (err) => {
            if (err) throw err;
        });
    });


    ну и вот пример того что бот будет записывать в папку logs (это лог с вашим сообщением моему боту :)
    {
      "content":"Тест",
      "attachments":[
        {
          "id":"686193341083549696",
          "url":"https://cdn.discordapp.com/attachments/452202521671237653/686193341083549696/IMG-30dd366b26acb4b1cbbe786f3ad22862-V.jpg",
          "proxyURL":"https://media.discordapp.net/attachments/452202521671237653/686193341083549696/IMG-30dd366b26acb4b1cbbe786f3ad22862-V.jpg",
          "filename":"IMG-30dd366b26acb4b1cbbe786f3ad22862-V.jpg",
          "filesize":58121,
          "height":330,
          "width":374
        }
      ]
    }


    каждое вложение содержит 2 ссылки (обычный url и proxyurl):

    url https://cdn.discordapp.com/attachments/45220252167...

    proxyurl https://media.discordapp.net/attachments/452202521...
    Ответ написан
  • Nodejs http-socks5proxy туннель?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    если речь идет именно о http (не https) запросах, то можно
    https://www.npmjs.com/package/shadowsocks-lite
    https://www.npmjs.com/package/http-proxy-to-socks
    Ответ написан
  • Как передать объект с сервера node.js?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Учите английский, в сообщении об ошибке все написано:
    The first argument must be one of type string ...


    Что можно перевести примерно так:
    Первый аргумент может быть только строкой.

    Таким образом чтобы передать JSON его надо преобразовать к строковому представлению:
    ws.send( JSON.stringify({'connected':25,"room":1000}));
    Ответ написан
  • Can't set headers after they are sent?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    думаю проблема тут:
    fs.writeFile(fullPath, base64Image, { encoding: 'base64' }, err => {
                if (err) return res.status(500).send(`Ошибка сохранения файла: ${err}`)
                else return
            });


    так как после этого куска кода не дожидаясь результата выполняется следом идущий код. Таким образом возможна ситуация, при которой send в этом куске кода выполнится уже после send-а в последующем коде

    попробуйте заменить этот код на:
    const promise = new Promise(resolve, reject)=>{
       fs.writeFile(fullPath, base64Image, { encoding: 'base64' }, err => {
          if (!err) return resolve(true);
          
          res.status(500).send(`Ошибка сохранения файла: ${err}`)
          return reject(false);
       });
    });
    const isWrite = await promise;
    if(!isWrite) return;
    Ответ написан
  • Как правильно создать новый файл в NodeJS?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    сначала создай директории в которых это файл лежит

    если версия ноды больше чем 10.12.00 то попробуйте так

    function saveFileSync(path, data){
      let list = path.split(/[\\\/]/);
      let filename = list.pop();
      let filepath = list.join('/');
      fs.mkdirSync(filepath, { recursive: true }, (err) => {
        if (err) throw err;
      });
      fs.writeFileSync(path, data);
    }
    
    
    
    let date = new Date();
    let filename = SSN + '_' + date.getFullYear() + '/' + date.getMonth() + '/' + date.getDay() + '_' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds() + '.txt';
    let text = ecg.join('');
    try{
        saveFileSync(filename, text);
    } catch (e) {
        console.log(e);
    }
    Ответ написан
  • Почему теряется контекст экземпляра класса?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Потому что он используется как мидлваре.
    Вызывайте его привязывая контент, както так

    const Authorized = require('../moduls/authorized')
    const auth = new Authorized();
    
    
    // так
    router.get("path/",auth.isAuthorized.bind(auth));
    // или так
    router.get("path/",(...a)=>auth.isAuthorized(...a));

    и еще кучей способов

    вот, можете почитать про Привязка контекста к функции

    а еще лучше измените метод isAuthorized примерно так:
    isAuthorized(){
       return (req, res, next)=>{
          console.log('isAuth',this)
          // тут код мидлвара
      }
    }


    и используйте его так
    router.get("path/",auth.isAuthorized());
    // или
    router.post("path/",auth.isAuthorized());
    // или
    router.use(auth.isAuthorized());
    Ответ написан
  • Как создать сессию?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    как показано в описании client-sessions помимо опции secret надо задать еще ряд опций, таких как cookieName (она же имя сессии) либо requestKey (requestKey overrides cookieName for the key name added to the request object).
    что позволит обращаться к сесcии через req

    ваш пример с исправлениями ошибок
    const express = require('express'),
        app = express(),
        port = 3000,
        clientSessions = require('client-sessions');
    
    app.use(clientSessions({
        secret: '0GBlJZ9EKBt2Zbi2flRPvztczCewBxXK', // set this to a long random string!
        cookieName: 'ss', // cookie name dictates the key name added to the request object
        requestKey: 'session', // requestKey overrides cookieName for the key name added to the request object.
    }));
    
    app.get('/',(request,response,next) => {
        request.session.username = 'qwer';
        response.send("вы обратились к /");
    });
    
    app.get('/1',(request,response,next) => {
        console.log(request.session.username);
        response.send("вы обратились к /1<br>в сессии сохранено: "+JSON.stringify(request.session));
    });
    
    app.listen(port,(err) => {
        if(err){
            return console.log(err);
        }
    
        console.log(`Слушается порт ${port}`);
    });


    PS: и не забывайте вызывать next(); там где требуется передать управление следующему обработчику или же request.end() или request.send(...) там где требуется прекратить дальнейшую обработку запроса

    PSPS: и пожалуйста, напишите в чем у вас возникли проблемы с ранее предложенным решением или отметьте его решением.
    Ответ написан
  • Как вынесли переменную?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Никак не вынесите, но это и не нужно. Вот мой ответ (немного сумбурный) на по сути такой же вопрос. Посмотрите его.
    Как запомнить текст, который выполняется в функции?

    Вот вариант, позволяющий писать код как если бы он был синхронным.
    // так как name.names(...) асинхронный, то для того, чтобы получить 
    // результат запроса в "синхронном стиле" используем await
    
    // await можно использовать только внутри асинхронной функции.
    // для этой цели обернем блок с вызовами name.names(...) в
    // само вызывающуюся асинхронную функцию
    (async () => {
    
       var n = await name.names('text', { data });
       console.log(n);
    
    })()
    Ответ написан
  • Как запомнить текст, который выполняется в функции?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Основная проблема в получении body заключена в том, что request асинхронный. То есть ответ придет не сразу, а через какое то время, при этом, js не будет дожидаться этого ответа а продолжит выполнять код, находящийся после request-а. Это в свою очередь приведет к тому, что в этом коде мы не можем получить ответ request-а, так происходит потому, что ответ еще не пришел)
    Как же быть в этой ситуации???
    Почитать про ассинхронность, промисы и async/await

    Далее привожу простенький класс, умеющий кэшировать ответы requesta, и пример его использования:
    тык сюда

    var request = require("request");
    
    
    // создаем класс для кэширования результатов запросов
    class СacheRequest {
    	// конструктор
    	constructor(handler){
    		// создаем ассоциативный массив для кэширования результата
    		this.cache = {};
    	}
    	
    	// основной метод класса, предназначен для получения данных по ссылке
    	// принимает url в качестве параметра
    	// возвращает выполненный промис если запрос есть в кэше
    	// или промис в ожидании выполнения запроса
    	async get(url){
    		// если такой запрос уже был, возвращаем промис с результатом из кэша
    		if( this.cache[url] )
    			return  Promise.resolve(this.cache[url]);
    		
    		// иначе возвращаем промис с ожиданием результата
    		return new Promise((resolve,reject)=>{
    			// делаем запрос на указаный url
    			request(url, (error, response, body)=>{
    				// если ошибка - реджектим )
    				if( error )
    					return reject(error);
    				
    				// иначе запоминаем в кэше ответ
    				this.cache[url] = body;
    
    				// и резолвим body
    				resolve(body);
    			});			
    		});
    	}
    
    	// метод отчищает кэш
    	clear(){
    		this.cache = {};
    	}
    }
    
    // создаем экземпляр кэша
    const cacheRequest = new СacheRequest();
    
    // так как request асинхронный, то для того, чтобы получить 
    // результат запроса в "синхронном стиле" используем await
    
    // await можно использовать только внутри асинхронной функции.
    // для этой цели обернем блок с вызовами cacheRequest.get в
    // само вызывающуюся асинхронную функцию
    (async () => {
    	// выполняем запросы:
    	// запросим "http://google.ru/" (будет сделан фактический запрос)
    	let body = await cacheRequest.get("http://google.ru/");
    	console.log("\n\n\nBODY:", body, 111);
    
    	// еще раз запросим "http://google.ru/" (будет взято из кэша)
    	body = await cacheRequest.get("http://google.ru/");
    	console.log("\n\n\nBODY:", body, 222);
    })()
    
    // раз в сутки отчищаем кэш
    setTimeout(()=>{
    	cacheRequest.clear();
    }, 1000*60*60*24 ); // 1000*60*60*24 это количество миллисекунд в сутках

    Ответ написан
  • Как подключить telegram бота в 2 файла?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    В tbot.js производите подключение бота и экспортируете уже подключенного бота (объект полученный при подключении бота)
    В остальных файлах require tbot и работаете уже с подключеным ботом.

    ЗЫ: но не забывайте, что все остальные файлы использующие бота должны запускаться в рамках одного процесса ноды.
    Если же вы будете их запускать по отдельности, это будет эквивалентно запуску нескольких экземпляров вашего бота и у вас опять все сломается.
    Есть несколько способов решения данной проблемы.
    1. Добавить в тбот прокси сервер на сокетах или вэбсокетах который будет содержать API на нужные вам функции бота. Далее из любого скрипта (в том числе и запущенного отдельно) подключаетесь к данному серверу и дергаете необходимые вам функции из API.
    2. Делаете 2х или более разных ботов (каждого со своим токеном)))
    3. Как писал выше, все файлы, использующие бота запускаете в рамках одного процесса, подключая их через require в главном файле проекта.

    ЗЫЗЫ: лично я делал бы по третьему варианту)
    Ответ написан
  • Где делать GET запрос в NodeJS или JS?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Если эти данные нужны только для отображения во фронте, делайте запрос во фронте
    Ответ написан
  • Как обрабатывать файлы не сервере правильно?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Как быть в случае, если путь до файла должен быть динамическим, например, по дням недели?

    Получая файл, в обработчике multer-а перемещаете файл в нужную вам папку (и переименовываете при необходимости). Это можно сделать как выполнив из ноды команду ОС (*nix, win), так и средствами самой ноды

    Выглядеть это будет примерно так:
    // роутер Express-а ./routes/files
    var fs = require('fs');
    var express = require('express');
    var router = express.Router();
    
    
    // получаем файлы
    var multer = require('multer');
    var upload = multer({ 
    	dest:'./folder_for_upload_files/'
    	// прочие опции
    }).single("upload");
    
    router.post('/files/upload', function(req, res, next) {
    	upload(req, res, function (err) {
    		if (err){
    		   // обработка ошибки
    		   // и завершение обработки запроса res.end() или res.send(...)
    		   return;
    		}
    		
    		// если же загрузка произошла успешно, то
    		// 1. определяем в какую папку и под каким именем переместить файл
    		// 2. перемещаем файл в нужную папку
    		// 3. делаем об этом запись в БД или в файлики или кудато еще (в место предназначенное для хранения этой информации)
    		// 4. завершаем обработки запроса ( res.end() или res.send(...) )
    		
    		// в помощь:
    		// req.file.originalname - оригинальное имя  файла на компе клиента
    		// req.file.filename - имя загруженного в "./folder_for_upload_files/" файла
    		
    		
    	});
    });
    
    
    module.exports = router;
    Ответ написан
  • Как заставить все запросы ждать один промис?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Как подсказал Inviz Custos, очередь решит вашу проблему (если конечно правильно будет работать с дублирующими запросами и промисами)

    Вот простенький рабочий пример
    // внутри async function
    let quiz = global_quizzes[quiz_id];
    if(!quiz) {
        global_quizzes[quiz_id] = quiz = Chat_Quizzes.findById(quiz_id).exec();
    }
    
    if( quiz instanceof Promise ){
        global_quizzes[quiz_id] = quiz = await quiz;
    } 
    chat.quiz = quiz;


    PS: правда это не совсем очередь, но ваш global_quizzes в некоторой степени ее имитирует.
    Ответ написан
  • Можно ли сделать переменные, определяемые в методе .exec, глобальными?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Для начала разбор Вашего варианта:
    var all_mail;
    mailModel.find().exec((err, docs) =>{
         // данный код не будет выполнен сразу, он будет выполнен только через какоето время.
         // дело в том, что пока бд сделает выборку и отдаст результат 
         // может пройти определенное время. Чтобы избежать простоев, 
         // в данном случае метод exec выполняется асинхронно
         // то есть тело данной функции будет вызвано не ранее чем от БД будут получены данные
         // а js тем временем продолжит выполнение кода дальше
         all_mail = docs;
    });
    
    // и придет сюда. но так как docs от БД еще не получен, all_mail все еще равен undefined.
    console.log(all_mail);  // Ошибка


    Теперь посмотрим как же нам добиться своевременной обработки результата:
    // добро пожаловать в асинхронность
    var all_mail;
    
    mailModel.find().exec((err, docs) =>{
         // в all_mail засовываем промис(обещание) того, что в скором времени будет результат
         all_mail  = new Promise((resolve, reject)=>{
               resolve(docs);
         });
    
    });
    
    all_mail.then((data)=>{
         // когда же результат будет получен, обрабатываем его
         console.log(data);  // все ок)
    });
    Ответ написан
  • Как запустить бинарный поток с клиента на сервер?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Можно, через websocket. Есть даже готовый npm пакет для этих целей websocket-stream

    Use HTML5 websockets using the Node Streams API.

    Usage
    This module works in Node or in Browsers that support WebSockets. You can use browserify to package this module for browser use.


    Или вам нужен чистый http?
    Ответ написан
  • Как запустить приложение на разных субдоменах?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Думаю самым простым и правильным решением будет разруливать субдомены и соответственно висящие на них приложения через nginx.

    Вы сможете запускать свои приложения как на одном хосте и даже в одном докер контейнере (на разных портах) так и на разных хостах и перенаправлять входящие по 80 порту запросы на ваши приложения по признаку субдомена. Так же вы сможете получив один сертификат выписанный для основного домена и субдоменов и подключив его через nginx, вы получите https не заморачиваясь настройкой и подключением сертификатов непосредственно в коде ваших приложений. Так же вы получите удобный инструмент балансировки нагрузки между вашими субдоменами и много других плюшек.
    Ответ написан