You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js如何读取URL参数、遍历ServerResponse及解决Express路由冲突

问题根因

  1. 授权回调的code是Spotify重定向回站点时携带的GET请求query参数,挂载在请求对象req上,你之前打印响应对象res当然找不到对应字段
  2. Express的路由匹配是从上到下优先匹配,两个相同路径、相同请求方法的路由只会执行第一个,因此需要拆分不同功能的路由路径

代码优化

1. 配置依赖启用

你引入了body-parser但未启用,先在初始化express后加配置:

const express = require("express");
const https = require("https");
const bodyParser = require("body-parser");
const axios = require("axios");

const app = express();
// 新增:启用body-parser解析表单和JSON请求体
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// 全局存储token,生产环境建议用缓存/数据库存储
let accessToken = '';

app.listen(3000, function() {
  console.log('服务启动在http://localhost:3000')
})

2. 调整路由逻辑

// 根路径GET请求:判断是否是授权回调,是则拿code换token,否则返回首页
app.get("/", function(req, res) {
  // 直接从请求query里拿code,就是你要的参数
  const code = req.query.code;
  if(code) {
    console.log('拿到授权code:', code);
    // 此处可以调用Spotify接口用code换access_token
    axios.post('https://accounts.spotify.com/api/token', new URLSearchParams({
      grant_type: 'authorization_code',
      code: code,
      redirect_uri: 'http://localhost:3000/',
      client_id: '替换为你的client_id',
      client_secret: '替换为你的client_secret'
    }), {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    }).then(tokenRes => {
      accessToken = tokenRes.data.access_token;
      console.log('拿到accessToken:', accessToken);
      // 拿到token后跳转回纯根路径,避免url里带code刷新重复请求
      res.redirect('/');
    }).catch(err => {
      console.error('换token失败:', err);
      res.send('授权失败');
    })
    return;
  }
  res.sendFile(__dirname + "/index.html");
});

const authURL = "https://accounts.spotify.com/authorize?client_id=替换为你的client_id&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2F&scope=user-read-playback-state%20app-remote-control%20user-modify-playback-state%20user-read-currently-playing%20user-read-playback-position%20user-read-email%20streaming"

// 授权跳转路由,单独拆分到/login路径
app.post("/login", function(req, res) {
  res.redirect(authURL);
});

// 搜索路由,单独拆分到/search路径
app.post("/search", function(req, res) {
  const query = req.body.queryValue;
  const searchUrl = "https://api.spotify.com/v1/search?q=" + encodeURIComponent(query) + "&type=track%2Calbum%2Cartist&limit=4&market=IN";

  axios.get(searchUrl, {
      headers: {
        'Authorization': `Bearer ${accessToken}`,
      }
    })
    .then((resAxios) => {
      console.log('搜索结果:', resAxios.data)
      // 此处处理返回结果返回给前端
      res.json(resAxios.data)
    })
    .catch((error) => {
      console.error('搜索失败:', error)
      res.status(500).send('搜索失败')
    })
});

3. 调整前端index.html代码

新增授权按钮,修改表单提交路径:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Title</title>
    <link rel="stylesheet" href="index.css">
  </head>
  <body>
    <!-- 新增授权按钮 -->
    <form action="/login" method="post" style="margin: 20px 0;">
      <button type="submit">Spotify授权登录</button>
    </form>
    <div class="index-search-container">
      <!-- 表单提交路径改为/search -->
      <form class="" action="/search" method="post">
        <input id="queryId" type="text" name="queryValue" value="" placeholder="Search">
        <button type="submit" name="button">HIT ME</button>
      </form>
    </div>
  </body>
</html>

关键说明

  • 直接通过req.query.code即可拿到授权回调的code参数,不需要解析日志
  • 路由拆分后不会再出现冲突,不同功能走不同路径逻辑更清晰
  • 搜索请求的query参数记得用encodeURIComponent编码,避免特殊字符导致请求错误

内容的提问来源于stack exchange,提问作者Varun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 20:36:10