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

React对接Spotify项目报illegal redirect_uri及ESLint错误求助

问题解决方案

一、核心illegal redirect_uri报错修复

这个报错的根因是构造Spotify授权链接时,误用单引号包裹模板字符串,导致变量根本没有被插值替换,实际传给Spotify的redirect_uri是字面量${redirectUri},和你在Spotify开发者后台配置的地址不匹配。
修复方法:Spotify.js中所有需要变量插值的字符串,全部把外围的单引号'换成反引号`。

二、ESLint告警逐一修复

1. SearchBar.js 重复方法告警

你定义了两次完全相同的handleTermChange方法,直接删除其中一个重复定义即可。

2. Spotify.js 变量未使用/模板字符串语法错误告警

所有告警的根源都是模板字符串语法错误,以及拼写错误:

  • 所有用到${变量}的字符串,全部把外围单引号换成反引号,替换后变量会被正常使用,no-unused-vars告警会自动消失
  • 修复拼写错误:
    • savePlayList方法中获取用户ID的字段是jsonResponse.id(注意小写i,原代码写的是大写I)
    • 第一个创建歌单的请求中变量名是userId,原代码写成了user_id
    • 第二个往歌单加曲目请求的接口路径写错了,正确路径是/v1/playlists/${playlistId}/tracks,原代码重复写了创建歌单的路径
    • 加曲目请求的body字段名是uris,原代码写成了大写开头的Uris

三、修复后的完整代码片段

SearchBar.js 修复后

import React from 'react';
import './SearchBar.css';

class SearchBar extends React.Component {
    constructor(props) {
        super(props);
        this.state ={
            term: ''
        }
        this.search = this.search.bind(this);
        this.handleTermChange = this.handleTermChange.bind(this);
    }

    search() {
        this.props.onSearch(this.state.term);
    }

    handleTermChange(event) {
        this.setState({term: event.target.value});
    }

    render() {
        return (
            <div className="SearchBar">
              <input onChange={this.handleTermChange} placeholder="Enter A Song, Album, or Artist" />
              <button className="SearchButton" onClick={this.search} >SEARCH</button>
            </div>
        )
    }
}

export default SearchBar;

Spotify.js 修复后

const clientId = '5e56a43c5001426189eda044053e2d30';
const redirectUri = 'http://localhost:3000/'

let accessToken;

const Spotify = {
    getAccessToken() {
        if (accessToken) {
            return accessToken;
        }

        const accessTokenMatch = window.location.href.match(/access_token=([^&]*)/);
        const expiresInMatch = window.location.href.match(/expires_in=([^&]*)/);

        if(accessTokenMatch && expiresInMatch) {
            accessToken = accessTokenMatch[1];
            const expiresIn = Number(expiresInMatch[1]);
            window.setTimeout(() => accessToken = '', expiresIn * 1000);
            window.history.pushState('Access Token' , null, '/');
            return accessToken;

        }else{
            // 单引号换反引号
            const accessUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirectUri}`
            window.location = accessUrl;
        }
    },

    search(term) {
        const accessToken = Spotify.getAccessToken();
        // 单引号换反引号
        return fetch(`https://api.spotify.com/v1/search?type=track&q=${term}`, 
        {headers: { 
            // 单引号换反引号
            Authorization:`Bearer ${accessToken}`
         }
        }).then(response => {
            return response.json();
        }).then(jsonResponse => {
            if(!jsonResponse.tracks) {
                return [];
            }
            return jsonResponse.tracks.items.map(track => ({
                id: track.id,
                name: track.name,
                artist: track.artists[0].name, 
                album: track.album.name,
                uri: track.uri
            }));
        }) ;
    },

    savePlaylist(name, trackUris) {
        if(!name || !trackUris.length) {
            return;
        }

        const accessToken = Spotify.getAccessToken();
        // 单引号换反引号
        const headers = {Authorization: `Bearer ${accessToken}`};
        let userId;

        return fetch('https://api.spotify.com/v1/me', {headers:headers}
        ).then(response => response.json()
        ).then(jsonResponse => {
            // 修复字段大小写
            userId = jsonResponse.id;
            // 单引号换反引号,修复变量名
            return fetch (`https://api.spotify.com/v1/users/${userId}/playlists`,
            {
                headers:headers,
                method:'POST',
                body: JSON.stringify({name: name})
            }).then(response => response.json()
            ).then(jsonResponse => {
                const playlistId = jsonResponse.id;
                // 修复接口路径,单引号换反引号
                return fetch(`https://api.spotify.com/v1/playlists/${playlistId}/tracks`,
                {
                    headers: headers,
                    method: 'POST',
                    // 修复字段名大小写
                    body: JSON.stringify({uris: trackUris})
                });
            })
        })
    }
}

export default Spotify;

额外检查项

请确认你在Spotify开发者后台的应用配置中,已经把http://localhost:3000/加到了Redirect URIs列表中,并且配置的地址和你代码里的redirectUri完全一致(包括末尾的斜杠)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:06:03