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

Flutter Web部署至GitHub Pages后无法调用Deezer API的问题

问题分析与解决

错误原因

这是浏览器同源策略引发的跨域资源共享(CORS)限制:

  • 本地运行时,开发环境(比如Flutter Web本地服务器)默认自带CORS代理,或者浏览器对本地文件的跨域校验宽松,所以请求能正常通过。
  • 部署到GitHub Pages后,应用域名是github.io,和Deezer API的deezer.com属于不同域名,浏览器会严格执行同源策略。当Deezer API的响应头没有允许github.io域名的跨域请求时,就会触发这个访问控制错误。另外原代码里Accept头设为application/xml,但后续要解析JSON,这个矛盾的请求头也可能干扰API的正常响应,间接影响CORS校验。

解决方法

方法1:使用Deezer API的JSONP请求方式

Deezer API支持JSONP格式,能绕过浏览器的CORS限制,修改代码如下:

import 'dart:html'; // 需要引入html库用于操作DOM

void searchForSongs(String searchString) async {
  // 构造JSONP请求URL,指定output为jsonp并设置回调函数名
  var url = Uri.parse('https://api.deezer.com/search?q=$searchString&output=jsonp&callback=handleDeezerResponse');
  
  // 创建script标签加载请求
  var script = ScriptElement()..src = url.toString();
  document.body!.append(script);
}

// 定义JSONP回调函数,处理API返回的数据
void handleDeezerResponse(dynamic data) {
  print(data);
  // 在这里处理歌曲数据的展示逻辑
}

方法2:搭建反向代理服务器

如果偏好使用常规的HTTP请求,可以搭建一个反向代理服务器,让代理转发请求到Deezer API,你的GitHub Pages应用请求代理服务器(同源)。以下是Node.js+Express的简单代理示例:

const express = require('express');
const axios = require('axios');
const app = express();

// 转发搜索请求到Deezer API
app.get('/deezer-search', async (req, res) => {
  try {
    const searchQuery = req.query.q;
    const deezerResponse = await axios.get(`https://api.deezer.com/search?q=${searchQuery}`);
    res.json(deezerResponse.data);
  } catch (err) {
    res.status(500).json({ error: '请求失败' });
  }
});

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`代理服务器运行在端口${PORT}`));

把这个代理部署到Vercel、Heroku等平台后,修改Dart代码的请求地址为你的代理接口:

void searchForSongs(String searchString) async {
  // 替换为你的代理服务器地址
  var url = Uri.parse('https://your-proxy-domain.com/deezer-search?q=$searchString');
  Map<String, String> requestHeaders = {
    'Content-type': 'application/json',
    'Accept': 'application/json',
  };
  var response = await http.get(url, headers: requestHeaders);
  var body = json.decode(response.body);
  print(body);
}

方法3:修正请求头(辅助优化)

原代码里的Accept头和后续JSON解析逻辑冲突,建议修正为:

Map<String, String> requestHeaders = {
  'Content-type': 'application/json',
  'Accept': 'application/json', // 匹配后续的JSON解析操作
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:41:20