Работающая функция более одного раза возвращает «ошибка: невозможно установить заголовки после их отправки»

Программа работает как надо, пока я не попытаюсь использовать функцию еще раз и она не вернет ошибка: невозможно установить заголовки после их отправки.

Я создаю это приложение, чтобы ознакомиться с nodejs и javascript, и я читал об ошибке, и это кажется проблемой при отправке более одного ответа на запрос. Я начал использовать res.setHeader, прежде чем узнал об этом, но я читал, что res.header может избежать этой проблемы, это не решило ее, но я сохранил ее.

HTML:

<!doctype html>
<head>
    <link rel = "stylesheet" type = "text/css" href = "youtube2music.css">
    <title>
        Youtube2Music
    </title>

</head>
<body>
    <div id = "cabeza">
        <h1>
            Youtube 2 Music
        </h1>
        <p>
            just paste your link below and download your song.
        </p>
    </div>
    <div id = "down-part">
        <input id = "myUrl" class='myUrl-input'>
        </input>
        <button type = "button" class = "download_button">
        Download
        </button>
    </div>
</body>
<script src='youtube2music.js'></script>
</html>

Javascript:

var urlinput = document.querySelector('.myUrl-input'); // gets url inputbox
var button = document.querySelector('.download_button'); // gets download button

button.addEventListener('click', () => {

  console.info(urlinput.value); // prints in console the url
  sendUrl(urlinput.value); // sends url to function to start the request

});

// function to make requst
function sendUrl(URL){

  window.location.href = `http://localhost:4000/?URL=${URL}`; // makes the video request to nodejs server
}

index.js < файл узла:

var eventEmitter = new events.EventEmitter();
var sfn;
appi.use(cors());
const {app, BrowserWindow} = require('electron')

function createWindow(){
  let win = new BrowserWindow({width:800, height:600});
  win.loadFile('index.html');
}
app.on('ready', createWindow)

appi.listen(4000, () => {
 console.info('server at port 4000');
});

appi.get('/',(req,res)=>{
 var URL = req.query.URL;
 ytdl.getInfo(URL, function(err,info){
   if (err) throw err;
   var songTitle = info.title;
   sfn = filenamify(songTitle);
   eventEmitter.emit('name_ready');
 });

 var startDownload = function(){
  let stream = ytdl(URL, {
   quality: 'highestaudio',
  });
  res.header('Content-Disposition', 'attachment; filename=' + sfn + '.mp3');
  res.header('Content-type', 'audio/mpeg');
  proc = new ffmpeg({source: stream})
  proc.withAudioCodec('libmp3lame').toFormat('mp3').output(res).run();
 }
 eventEmitter.on('name_ready', startDownload);
})

поскольку это работает для первого ввода, но запрос другого вывода приводит к ошибке, почему он действительно возвращает эту ошибку и как ее можно избежать?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
34
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Есть несколько проблем с вашей текущей настройкой:

  1. Старайтесь не использовать эмиттер событий для сигнализации о событиях в HTTP-запросе, он не был создан для этого.
  2. С HTTP-запросами старайтесь не использовать глобальные переменные для данных, полученных во время запроса, когда два запроса приходят одновременно, они могут запутаться и получить неправильные данные.
appi.listen(4000, () => {
 console.info('server at port 4000');
});

appi.get('/', (req,res)=> {
  const { URL } = req.query;
  ytdl.getInfo(URL, (err,info) => {
    if (err) throw err;
    const songTitle = info.title;
    const sfn = filenamify(songTitle);
    let stream = ytdl(URL, {
      quality: 'highestaudio',
    });
    res.set('Content-Disposition', 'attachment; filename=' + sfn + '.mp3');
    res.set('Content-type', 'audio/mpeg');
    const proc = new ffmpeg({source: stream})
    proc.withAudioCodec('libmp3lame').toFormat('mp3').output(res).run();
  });
})

Я не думал об использовании const спасибо, не могли бы вы объяснить, почему res.set используется в этом случае?

Thriskel 09.04.2019 23:36
res.set — документированная версия res.header: набор рез..
dotconnor 09.04.2019 23:41

Другие вопросы по теме