API NodeJS fetch() и POST-запрос

#javascript #node.js #express #post #fetch

#javascript #node.js #экспресс #Публикация #выборка

Вопрос:

Ниже приведена часть HTML-кода, которая позволяет клиенту вводить почтовый индекс США и ощущение дня. Приложение будет извлекать данные о погоде на основе почтового индекса, предоставленного через вызов API api.openweathermap.org/data/2.5/weather?zip={zip code},{country code}amp;appid={API key} . Вы можете обратиться к документации здесь .

       <div class="holder zip">
        <label for="zip">Enter Zipcode here</label>
        <input type="text" id="zip" placeholder="enter zip code here" />
      </div>
      <div class="holder feel">
        <label for="feelings">How are you feeling today?</label>
        <textarea
          class="myInput"
          id="feelings"
          placeholder="Enter your feelings here"
          rows="9"
          cols="50"
        ></textarea>
        <button id="generate" type="submit">Generate</button>
      </div>
  

Вот интерфейс JS-скрипта <app.js > это позволит получить доступ к API погоды, загрузить данные и сохранить их в app_info (см. downloadAPI()). После завершения используйте postData() для отправки данных на сервер (см. server.js ниже) с запросом POST. postData() — это тег для EventListener, созданный для кнопки «Сгенерировать».

 /* Global Variables */
var app_input = "";

// variable for Zip Code
const userInput = document.getElementById("zip");
let zipCode = userInput.value;

// eventListener to update Zip Code
userInput.addEventListener("input", function () {
  zipCode = userInput.value;
  // app_input.zipCode = zipCode;
});

// variable for user feeling
const userText = document.getElementById("feelings");
let userFeedback = userText.value;

// eventListener to update user feeling
userText.addEventListener("input", function () {
  userFeedback = userText.value;
  // app_input.userFeedback = userFeedback;
});

// function to extract Weather API data
async function downloadAPI(code) {
  const response = await fetch(
    `http://api.openweathermap.org/data/2.5/weather?zip=${code},usamp;units=metricamp;appid=d38ab121caf0ee2480e43210276b8001`
  );

  const data = await response.json();
  let country = data.sys.country;
  let city = data.name;
  let temperature = data.main.temp;
  let condition = data.weather[0].description;

  app_input = {
    location: `${country}, ${city}, ${zipCode}`,
    weather: `${condition}`,
    temperature: `${temperature}`,
    comment: `${userFeedback}`,
  };
}

// variable for Generate button
const form = document.getElementById("generate");

async function postData() {
  downloadAPI(zipCode);

  const response = await fetch("/", {
    method: "POST",
    mode: "cors",
    credentials: "same-origin",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(app_input),
  });

  try {
    const appData = await response.json();
    return appData;
  } catch (error) {
    console.log("warning: ", error);
  }
}

// eventListener for Generate button
form.addEventListener("click", postData);
  

Ниже приведен код на стороне сервера <server.js >. На данный момент я использую POST-запрос только для регистрации данных из app_info. Позже эта часть будет улучшена.

 // Require Express to run server and routes
const express = require("express");

// Start up an instance of app
const app = express();

/* Dependencies */
const bodyParser = require("body-parser");

/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// Cors for cross origin allowance
const cors = require("cors");
app.use(cors());

// Initialize the main project folder
app.use(express.static("website"));

// Setup empty JS object to act as endpoint for all routes
const projectData = Array();

app.post("/", function (req, res) {
  console.log(res.body);
});

// Setup Server
const port = 3000;

function listening() {
  console.log(`server running on localhost: ${port}`);
}

const server = app.listen(port, listening);

  

Страница успешно загружена. Я ввожу почтовый индекс: 90001 и «Я чувствую себя хорошо»; затем нажмите на кнопку «Сгенерировать».

Сеть в консоли показывает, что JS успешно извлекает данные о погоде.

введите описание изображения здесь

Обнаружена ошибка при app.js <Строка 50 и строка 64>

введите описание изображения здесь

который здесь:

 const response = await fetch("/", { //Error!!!
    method: "POST",
    mode: "cors",
    credentials: "same-origin",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(app_input),
  });

  try {
    const appData = await response.json();
    return appData;
  } catch (error) {
    console.log("warning: ", error); //Error!!!
  }
  

Пожалуйста, сообщите, где я допустил ошибку.

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

1. Почему вы используете POST, когда в вашем примере URL-адреса используются параметры запроса.? кстати: Unexpected token < in JSON обычно сервер отправляет HTML, посмотрите на вкладке сети вашего браузера, чтобы увидеть, что он возвращает.

2. @Keith можете ли вы подробнее рассказать о параметрах POST и query? Я новичок. Кстати, я вношу изменения в свой вопрос для лучшего разъяснения. Пожалуйста, помогите.

Ответ №1:

Вы не ожидаете downloadAPI() в функции postData, и поэтому значение этого API не сохраняется в переменной app_info. Возможно, это ваша проблема

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

1. Я обновил свой код, и снимок экрана сети в консоли показывает, что мой код загрузил данные API погоды. Однако в следующей строке после downloadAPI() произошел сбой в функции postData().

2. попробуйте войти response.text() непосредственно перед этим await response.json() . Является ли ответ json?

3. Вот текст в консоли JS Promise {<pending>} __proto__: Promise [[PromiseState]]: "fulfilled" . Результатом ответа является HTML-документ. Очень длинный HTML-строки начинаются с <!DOCTYPE html> ~~~~

4. а ты await response.text() ? Каков статус и ответ на первоначальный вызов api из fetch ? Это в формате json?

5. Я пытаюсь try { const text = await response.text(); console.log(text); const appData = await response.json(); return appData; } catch (error) { console.log("warning: ", error); } , и результат <pre> в HTML с надписью ==> SyntaxError: неожиданный токен » в JSON в позиции 0.