Попытка отправить правильный заголовок с помощью Express, Tedious при доступе к Azure SQL

Мой сервер получает запрос на получение записей из базы данных SQL Azure. Для управления этими запросами я использую Express в Nodejs и Tedious (для подключения к БД). Когда приходит запрос на соответствующий маршрут, Tedious открывает соединение с db, запрашивает его и должен отправить ответ обратно во внешний интерфейс.

Однако код отвечает до того, как я получу ответ из базы данных, и поэтому, когда я собираюсь отправить настоящий (фактически желаемый) ответ, Express сообщает мне, что он уже отправил заголовки обратно (ужасный: «Невозможно установить заголовки после их отправки клиенту»).

После небольшой отладки (используя несколько console.log(JSON.stringify(resp.headersSent)); ), чтобы увидеть, когда действительно был отправлен ответ, я заметил, что он был отправлен в тот момент, когда я подключаюсь к Azure (см. ниже).

Я не уверен, что я что-то упускаю (хотя я уже немного проверил документацию по всем этим программам), но как я могу контролировать, когда отправляется ответ? Или есть другой способ сделать это.

Я опустил несколько других маршрутов для краткости. Другие маршруты работают нормально, и поэтому я знаю, что код хорошо подключается к Azure db, а внешний интерфейс правильно запрашивает серверную часть. Помощь приветствуется. Спасибо.

const express = require('express');
const cors = require('cors');
const Connection = require('tedious').Connection;
const Request = require('tedious').Request;

const config = {
  authentication: {
    options: {
      userName: "xxxx", 
      password: "xxxx" 
    },
    type: 'default'
  },
  server: "xxxx", 
  options: {
    database: "xxxx",
    encrypt: true
  }
};

const app = express();
app.use(express.json({type: '*/*'}));
app.use(cors({ origin: '*' }));

app.get("/allproj/", function (req, resp) {
  const q = `select Title, Report_Date, Project_Number, Phase_Code, Items_No, PId from projec order by PId desc`;
  let ansf = [];
  
  const connection = new Connection(config);

  connection.on('connect', (err, connection) => {
    if (err) {
      console.log(err);
    } else {                  //this is the moment the headers are sent, 
                              //seemingly with positive response from connection
      queryItems(q);
    }
  });
  
  queryItems = (q) => {

    request = new Request(q, function (err, rowCount) {
      if (err) {
        console.log(err);
      } else {
        console.log(rowCount + ' rows pulled');
        connection.close();
      }
    });

    request.on('row', function(columns) {
      let ans = [];
      columns.forEach(function(column) {
        ans.push(column.value);
        if (ans.length === 6) {  // I know each row is 6 cols long
          ansf.push(ans);
          ans = [];
        }
      });
      console.log('ansf length: ' + ansf.length);
      resp.send({ ansf });          // This is the response I would like to return
    });

    request.on('done', function(rowCount) {
      console.log(rowCount + ' rows returned');
      connection.close();
    });

    connection.execSql(request);    
  };

  resp.redirect("/");
});

app.listen(3000, process.env.IP, function() {
  console.log("Started OK...");
});

person Hashi    schedule 27.07.2020    source источник


Ответы (1)


Удалить resp.redirect(/); Поскольку он уже передает ваш запрос в / и когда управление поступает в resp.send({ansf}), выдается ошибка.

person Prateek Agarwal    schedule 27.07.2020
comment
Спасибо, это был хороший улов. Мне все еще пришлось изменить пару других вещей, чтобы код отправлял ответ, когда я хотел, но ваш ответ очень помог! - person Hashi; 28.07.2020