如何用脚本修改DOM元素?解决leaguejs引入及CORS报错问题
问题分析与解决方案
看起来你遇到了两个核心问题:一是JavaScript代码里的Promise嵌套逻辑冗余,二是Node.js模块直接在浏览器运行导致的CORS和环境不兼容问题。下面一步步帮你解决:
1. 先修复Promise逻辑问题
你的原代码里重复调用了leaguejs.Summoner.gettingById,属于冗余操作,而且多层嵌套的Promise会导致"回调地狱",可读性和可维护性都很差。可以用async/await或者链式Promise来优化:
优化后的async/await版本
const summonerId = 'EXzNQLirRTxF_-l5-MYhE0RN-1i5rO-TDmHmdEzgf3psI94'; const accountId = 'BteGB3awYZqnAzYXnR2Bfo9NcqxvbP4DW-tsvJ5LR_u9rejnu2ArF5Gc'; const documentToChange = document.getElementById("replace"); async function fetchSummonerName() { try { // 优先用summonerId获取召唤师信息 const data = await leaguejs.Summoner.gettingById(summonerId, 'oce'); documentToChange.innerHTML = `Lunami's Current Username Is: "${data.name}"`; } catch (err) { try { // 失败后用accountId重试 const datE = await leaguejs.Summoner.gettingByAccount(accountId, 'oce'); documentToChange.innerHTML = `Lunami's Current Username Is: "${datE.name}"`; } catch (secondErr) { // 两次都失败的兜底提示 documentToChange.innerHTML = "Lunami's Broken ;-;"; } } } fetchSummonerName();
链式Promise版本(如果不习惯async/await)
const summonerId = 'EXzNQLirRTxF_-l5-MYhE0RN-1i5rO-TDmHmdEzgf3psI94'; const accountId = 'BteGB3awYZqnAzYXnR2Bfo9NcqxvbP4DW-tsvJ5LR_u9rejnu2ArF5Gc'; const documentToChange = document.getElementById("replace"); leaguejs.Summoner.gettingById(summonerId, 'oce') .then(data => { documentToChange.innerHTML = `Lunami's Current Username Is: "${data.name}"`; }) .catch(err => { // 第一次失败后,返回第二个Promise继续链式调用 return leaguejs.Summoner.gettingByAccount(accountId, 'oce'); }) .then(datE => { if (datE) { documentToChange.innerHTML = `Lunami's Current Username Is: "${datE.name}"`; } }) .catch(finalErr => { documentToChange.innerHTML = "Lunami's Broken ;-;"; });
2. 解决CORS与模块加载的核心问题
你遇到的Access to script at 'file:///...' blocked by CORS错误,本质是两个原因:
leaguejs是Node.js专用包,依赖Node的http等核心模块,浏览器环境没有这些,所以不能直接在前端代码里用require或import引入。- 直接用
file://协议打开HTML文件,会触发浏览器的安全限制,不允许跨域请求(甚至本地文件之间的请求)。
下面是两个可行的解决方案:
方案一:搭建Node.js后端代理(推荐,安全可靠)
Riot API密钥绝对不能暴露在前端代码里(会被窃取滥用),所以正确的做法是用后端作为中间层,前端请求自己的后端接口,后端再调用Riot API并返回结果。
步骤1:初始化后端项目
mkdir summoner-tracker && cd summoner-tracker npm init -y npm install leaguejs express cors
步骤2:编写后端代码(server.js)
const express = require('express'); const cors = require('cors'); const Leaguejs = require('leaguejs'); const app = express(); app.use(cors()); // 允许前端跨域请求 const leaguejs = new Leaguejs("你的Riot API密钥"); // 这里放你的密钥 // 定义获取召唤师名称的接口 app.get('/get-summoner', async (req, res) => { const summonerId = 'EXzNQLirRTxF_-l5-MYhE0RN-1i5rO-TDmHmdEzgf3psI94'; const accountId = 'BteGB3awYZqnAzYXnR2Bfo9NcqxvbP4DW-tsvJ5LR_u9rejnu2ArF5Gc'; try { const data = await leaguejs.Summoner.gettingById(summonerId, 'oce'); res.json({ name: data.name }); } catch (err) { try { const datE = await leaguejs.Summoner.gettingByAccount(accountId, 'oce'); res.json({ name: datE.name }); } catch (secondErr) { res.status(500).json({ msg: "Lunami's Broken ;-;" }); } } }); // 启动后端服务 app.listen(3000, () => { console.log('后端服务运行在 http://localhost:3000'); });
步骤3:修改前端代码(index.js)
const documentToChange = document.getElementById("replace"); // 请求自己的后端接口 fetch('http://localhost:3000/get-summoner') .then(res => res.json()) .then(result => { if (result.name) { documentToChange.innerHTML = `Lunami's Current Username Is: "${result.name}"`; } else { documentToChange.innerHTML = result.msg; } }) .catch(err => { documentToChange.innerHTML = "Lunami's Broken ;-;"; });
步骤4:运行项目
- 启动后端:
node server.js - 用本地服务器打开HTML文件(比如用
npx live-server命令启动,避免file://协议问题)
方案二:纯前端直接调用Riot API(仅适合本地测试)
如果只是临时测试,可以跳过后端,直接用fetch调用Riot API,但注意:API密钥会暴露在前端代码里,非常不安全,绝对不能用于正式环境。
步骤1:修改前端代码(index.js)
const documentToChange = document.getElementById("replace"); const apiKey = "你的Riot API密钥"; const summonerId = 'EXzNQLirRTxF_-l5-MYhE0RN-1i5rO-TDmHmdEzgf3psI94'; const accountId = 'BteGB3awYZqnAzYXnR2Bfo9NcqxvbP4DW-tsvJ5LR_u9rejnu2ArF5Gc'; async function fetchSummoner() { try { // 用summonerId请求Riot API const res = await fetch(`https://oc1.api.riotgames.com/lol/summoner/v4/summoners/${summonerId}`, { headers: { 'X-Riot-Token': apiKey } }); const data = await res.json(); documentToChange.innerHTML = `Lunami's Current Username Is: "${data.name}"`; } catch (err) { try { // 失败后用accountId请求 const res = await fetch(`https://oc1.api.riotgames.com/lol/summoner/v4/summoners/by-account/${accountId}`, { headers: { 'X-Riot-Token': apiKey } }); const datE = await res.json(); documentToChange.innerHTML = `Lunami's Current Username Is: "${datE.name}"`; } catch (secondErr) { documentToChange.innerHTML = "Lunami's Broken ;-;"; } } } fetchSummoner();
步骤2:用本地服务器打开HTML
安装并启动live-server:
npx live-server
然后访问控制台输出的http地址(比如http://localhost:8080),这样就不会有CORS问题了。
内容的提问来源于stack exchange,提问作者Supesu




