React and Express iTunes Search API :: Error: Request failed with status code 404

React and Express iTunes Search API :: Error: Request failed with status code 404

我目前正在使用 API 创建 iTunes 搜索应用程序,但在尝试获取数据以组合结果组件时遇到困难。

在其他资源中,我参考了以下信息: iTunes Search API

请看下面我的代码:

后端 - 控制器 - index.js

// Requiring Express.
const express = require("express");
// Requiring fetch from Node Fetch.
const fetch = require("node-fetch");

exports.getController =
  ("/search",
  (req, res) => {
    fetch(
      `https://itunes.apple.com/search?term=${req.query.name}&limit=30&media=${req.query.type}`
    )
      .then((res) => res.json())
      .then((results) => {
        res.send(results);
      });
  });

后端 - 路由 - index.js

// Requiring Express.
const express = require("express");
// Requiring Router from Express.
const router = express.Router();
// Requiring controllers from the controllers folder's index.js.
const { getController } = require("../controllers/index.js");

router.get("/search", getController);

// Exporting controllers to server.js.
module.exports = router;

后端 - server.js

// Requiring Express.
const express = require("express");
// Requiring Morgan.
const morgan = require("morgan");
// Requiring CORS.
const cors = require("cors");
// Initializing express with variable "app".
const app = express();
// Requiring the routes index.js file.
const routes = require("./routes/index.js");
// Requiring Helmet.
const helmet = require("helmet");

/**
 * Enabling App usages.
 */

const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.use(express.json());
app.use(morgan("start"));
app.use(cors());
app.use(helmet());

app.use("/", routes);

const path = require("path");
if (process.env.NODE_ENV === "production") {
  app.use(express.static("frontend/build"));
  app.get("*", (req, res) => {
    res.sendFile(path.resolve(__dirname, "frontend", "build", "index.html"));
  });
}

const PORT = process.env.PORT || 8080;
app.listen(PORT);
console.log(
  "Navigate to http://localhost:8080/search. Server is listening on port",
  PORT
);

app.use(function (err, req, res, next) {
  console.log(err.stack);
  res.status(500).send("Something broke!");
});

前端 - search.js

// Imported react libraries and hooks.
import React, { useState, useEffect } from "react";
import axios from "axios";
// Imported Link from React Router Dom.
import { Link } from "react-router-dom";
// Imported components from React Bootstrap.
import { Row, Dropdown, ButtonGroup, Button } from "react-bootstrap";
// Imported icons from FontAwesome.
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSearch } from "@fortawesome/free-solid-svg-icons";
// Imported components.
import Results from "./results.js";

const Search = () => {
  const [name, setName] = useState("");
  const [type, setType] = useState("");
  const [results, setResults] = useState([]);
  const [favourites, setFavourites] = useState([]);

  const addToFav = (fav) => {
    setFavourites([...favourites, fav]);
  };

  useEffect(() => {
    localStorage.setItem("Favourites", JSON.stringify(favourites));
  }, [favourites]);

  const submitSearch = (e) => {
    e.preventDefault();

    axios
      .get(`/search/${name}/${type}`, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
        },
      })
      .then((res) => {
        const queryAdded = res.data.results;
        setResults(queryAdded ? queryAdded : []);
      })
      .catch((err) => {
        console.log(err);
      });
  };

  let nameEntry = "";
  const nameSubmit = (e) => {
    const entry = e.target.value;
    nameEntry = entry;
    setName(nameEntry);
  };

  const categories = [
    { name: "MUSIC", value: "music" },
    { name: "MUSIC VIDEO", value: "musicVideo" },
    { name: "APPS", value: "software" },
    { name: "EBOOK", value: "ebook" },
    { name: "AUDIO BOOK", value: "audiobook" },
    { name: "PODCAST", value: "podcast" },
    { name: "MOVIES", value: "movie" },
    { name: "TV SHOW", value: "tvShow" },
    { name: "SHORT FILM", value: "shortFilm" },
  ];

  return (
    <div id="searchcontainer">
      <div id="searchcontent">
        <div id="searchinput">
          <input
            type="text"
            placeholder="Search..."
            name="name"
            onChange={nameSubmit}
          />
          <Link to={`/search`}>
            <button id="searchbutton" type="submit" onClick={submitSearch}>
              <FontAwesomeIcon icon={faSearch} title="Search" />
            </button>
          </Link>
        </div>

        <Dropdown as={ButtonGroup}>
          <Button variant="info" size="sm">
            CATEGORIES
          </Button>
          <Dropdown.Toggle
            split
            variant="info"
            id="dropdown-split-basic"
            drop="bottom"
          />

          <Dropdown.Menu>
            {categories.map((category, i) => (
              <Dropdown.Item
                as="button"
                key={i}
                id="searchcategories"
                value={category.value}
                checked={type === category.value}
                onChange={(e) => setType(e.currentTarget.value)}
              >
                {category.name}
              </Dropdown.Item>
            ))}
          </Dropdown.Menu>
        </Dropdown>
      </div>

      <div className="search-page">
        <div className="container-fluid">
          <Row md={5}>
            {results.length !== 0 ? (
              results.map((content) => (
                <Results addToFav={addToFav} content={content} />
              ))
            ) : (
              <h1></h1>
            )}
          </Row>
        </div>
      </div>
    </div>
  );
};

// Exported search.js to landing.js.
export default Search;

不幸的是,我收到以下错误:

我已经尝试了几件事,但似乎没有任何效果。事实上,我认为我的所有操作可能会使代码过于复杂。

如果有人愿意提供任何帮助,我将不胜感激。

有几个问题:

  • 当前,您正在向 React 应用地址 (http://localhost:3000) 发送请求。您需要将请求发送到 NodeJS 应用程序。
 axios
      .get(`http://localhost:8080/search/${name}/${type}`, { // add the address of NodeJS application
  • 如果你想发送这样的数据/search/${name}/${type},那么在后台,req.query是行不通的。您应该使用 req.params 并相应地更改您的路线。阅读 Express 文档 here。或者,您需要将前端部分的 URL 更改为 /search/?name={name}&type=${type}
  • 最后,在日志中,URL 是 http://localhost:3000/search/korn。缺少 1 个参数,这可能会给您的后端应用程序带来错误的 URL。 https://itunes.apple.com/search?term=${req.query.name}&limit=30&media=${req.query.type} 可能会导致 https://itunes.apple.com/search?term=korn&limit=30&media=undefined 您需要一种机制来处理丢失的数据。