You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用脚本修改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等核心模块,浏览器环境没有这些,所以不能直接在前端代码里用requireimport引入。
  • 直接用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:运行项目

  1. 启动后端:node server.js
  2. 用本地服务器打开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

火山引擎 最新活动