我如何将搜索结果发送回客户端?

问题描述 投票:0回答:1

我正在制作一个使用Spotify API的网络应用。我想从客户端获取搜索关键字,并将其搜索结果发送回客户端。我正在使用搜索关键字“ http://localhost:4000/search_result”发出发布请求,然后将结果发送回“ http://localhost:4000/api”,然后获取数据。当我在Chrome开发者工具上查看“网络”时,获取404进行调用。而且我还想知道是否有办法在server.js的发帖请求中使用发帖请求中的search关键字。

Main.js

import React, { Component } from "react";
import SingerCard from "./SingerCard";
import axios from "axios";

export class Main extends Component {
  constructor(props) {
    super(props);
    this.state = {
      keyword: "",
      artists: [],
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(e) {
    this.setState({ keyword: e.target.value });
  }

  handleSubmit(e) {
    e.preventDefault();
    axios
      .post(
        "http://localhost:4000/search_result",
        {
          keyword: this.state.keyword,
        },
        {
          headers: {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*",
            // Accept: "application/json",
          },
        }
      )
      .then(function (res) {
        console.log(res);
      })
      .catch(function (err) {
        console.log(err);
      });
  }

  componentDidMount() {
    fetch("http://localhost:4000/api")
      .then((res) => res.json())
      .then((artists) => {
        this.setState({ artists });
      })
      .catch((err) => console.log);
  }

  render() {
    return (
      <div className="main">
        <form onSubmit={this.handleSubmit}>
          <label htmlFor="search">Search an artist: </label>
          <span>
            <input
              type="search"
              value={this.state.keyword}
              onChange={this.handleChange}
              name="keyword"
            />

            <button type="submit" value="Submit">
              Search
            </button>
          </span>
        </form>
        <br />

        <div className="container">
          {this.state.artists.map((elem) => (
            <SingerCard
              images={elem.images}
              name={elem.name}
              artists={this.state.artists}
            />
          ))}
          {console.log("Arists are: " + this.state.artists)}
        </div>
        <br />
      </div>
    );
  }
}

export default Main;

server.js

const express = require("express");
const SpotifyWebApi = require("spotify-web-api-node");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();

const port = 4000 || process.env.PORT;
require("dotenv").config();

app.use(express.json());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));

// Create the api object with the credentials
var spotifyApi = new SpotifyWebApi({
  clientId: process.env.CLIENT_ID,
  clientSecret: process.env.CLIENT_SECRET,
});

// Retrieve an access token.
spotifyApi.clientCredentialsGrant().then(
  function (data) {
    console.log("The access token expires in " + data.body["expires_in"]);
    console.log("The access token is " + data.body["access_token"]);

    // Save the access token so that it's used in future calls
    spotifyApi.setAccessToken(data.body["access_token"]);
  },
  function (err) {
    console.log("Something went wrong when retrieving an access token", err);
  }
);

app.post("/search_result", (req, res) => {
  console.log(req.body.keyword);
  spotifyApi.searchArtists(req.body.keyword).then(function (data) {
    console.log(data.body);
    var search_res = data.body.artists.items;

    app.get("/api", (req, res) => {
      res.json(search_res);
      res.end();
    });

    res.end();
  }),
    function (err) {
      console.log(err);
    };
});

app.listen(port, () => console.log(`It's running on port ${port}`));

node.js reactjs express
1个回答
0
投票

您的服务器端路由应配置一次,而不是即时配置。当您调用app.postapp.get时,您正在配置一条路由并提供一个回调,该回调将在每次传入匹配该路由的请求时使用。在您的代码中,创建一个后路由,然后在处理程序中创建一个get路由。不要那样做。

HTTP服务器是无状态的。这意味着每个请求(发布,获取)都不了解彼此。如果要共享信息,则可以通过数据库(内存中,redis,nosql,sql等)进行共享,其中每个路由仅使用传递给它的参数。

例如,POST路由为搜索结果创建一个ID。 POST路由返回此ID。 GET路由在被调用时,应接收相同的ID并查找结果。当然,这仅对于非常长的流程(通常是作业队列)才需要。对于您的特定情况,您只需要一条路线。

app.post("search_result", (req, res) => {
  console.log(req.body.keyword);
  spotifyApi
    .searchArtists(req.body.keyword)
    .then(
      function(data) {
        console.log(data.body);
        var search_res = data.body.artists.items;

        res.json(search_res);
        res.end();
      },
      function (err) {
        console.log(err);
        res.status(500).send(err);
      }
    );
});

并且不要忘记删除您的componentDidMount代码,因为您只需要调用POST路由。

  handleSubmit(e) {
    e.preventDefault();
    axios
      .post(
        "http://localhost:4000/search_result",
        {
          keyword: this.state.keyword,
        },
        {
          headers: {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*",
            // Accept: "application/json",
          },
        }
      )
      .then(function (res) {
        console.log(res);
        this.setState({ artists });
      })
      .catch(function (err) {
        console.log(err);
      });
  }
© www.soinside.com 2019 - 2024. All rights reserved.