Независимо от того, как я устанавливаю res.format() в Express, данные всегда анализируются в зависимости от метода анализа fetch(). Почему?

#javascript #node.js #express #format

Вопрос:

Я не понимаю, как это res.format() работает. Я прочитал всю документацию, плюс несколько ответов здесь, на stackoverflow, но на самом деле они не затрагивают ту часть, которая меня смущает.

 app.get('/', (req, res) => {

     res.format({
         'text/html' : function() { 
             res.send({name: 'romeo'})
         }
     })
}) 

В приведенном выше примере я устанавливаю формат 'text/html' , но на самом деле я отправляю объект JS.

Итак, теперь на стороне клиента:

         fetch(req)
        .then(res=>res.json())
        .then(content=> {
            //output.innerHTML = JSON.stringify(content, 'n', 2);
            console.log(content)
            output.innerHTML = content;
        }) 
        .catch(err=>console.eror); 

Если я использую json() , данные будут просто проанализированы в объект JS, независимо от того, что я отправляю, и независимо от того, что я установил res.format() . Почему? Вот чего я не понимаю.

Даже если я задам формат 'application/json' , я могу просто отправить обычный текст, а затем, если я использую json() его снова, он снова вернет объект JS.

И наоборот, если я отправлю объект JS, но text() вместо этого использую его, он будет проанализирован в текст.

Итак, что именно делает этот формат?

Да, я читал, что он должен проверять Accept заголовок HTTP-запроса, а затем вызывать соответствующий обработчик в соответствии Accept со значением, но на самом деле это мне ни о чем не говорит. Я не устанавливаю заголовок запроса, и независимо от того , как я его устанавливаю format() , фактический формат данных всегда определяется методом синтаксического анализа, который я выбираю json() для объекта JS, text() текста или html. Я не вижу цели в том, чтобы устанавливать format() А.

Комментарии:

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

2. Вы просите способ автоматического анализа выборки в соответствии с типом контента, заданным форматом? Что вы хотите вернуть, JSON или текст?

3. @PatrickEvans Итак, даже если я не использую format() , сервер установит его автоматически в зависимости от типа данных, верно? Кстати, сервер всегда преобразует данные в JSON перед отправкой, правильно? Даже если я отправляю обычный текст, он все равно сначала превращается в JSON, верно?

4. @AlexanderStaroselsky Есть ли такой способ?

5. Вы можете условно вызвать text или json на основе типа содержимого res. заголовки res.должны иметь заголовок типа содержимого, из которого вы можете сделать поворот.

Ответ №1:

res.format(object) используется таким образом, чтобы клиент мог указать, какой тип контента он хочет вернуть. Клиент указывает эту информацию, используя Accepts заголовок в своем запросе.

Чтобы узнать больше о res.format(object) посещении https://expressjs.com/en/5x/api.html#res.format

Чтобы узнать больше о Accepts заголовке, посетите https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept

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

Код сервера

 const express = require("express");

const PORT = process.env.PORT || 5000;
const app = express();

app.get('/', function (req, res) {
  res.format({
    'text/plain': function () {
      res.send('text')
    },
  
    'text/html': function () {
      res.send('<p>html</p>')
    },
  
    'application/json': function () {
      res.send({ message: 'json' })
    },
  })
})

app.listen(PORT, () => {
  console.log("Listening on port: "   PORT);
}); 
 

Код клиента

 const fetch = require("node-fetch");

fetch('http://localhost:5000/', {
  headers: {
    'Accept': 'text/html'
  }
})
.then(res => res.text())
.then(res => {
  console.log(res) // <p>html</p>
});

fetch('http://localhost:5000/', {
  headers: {
    'Accept': 'text/plain'
  }
})
.then(res => res.text())
.then(res => {
  console.log(res) // text
});

fetch('http://localhost:5000/', {
  headers: {
    'Accept': 'application/json'
  }
})
.then(res => res.json())
.then(res => {
  console.log(res) // { message: 'json' }
});