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

静态HTML页面使用原生JavaScript获取远程JSON元数据时跨域请求被阻止的原因问询

解决跨域Fetch请求的CORS错误问题

问题分析

你碰到的这个Cross-Origin Request Blocked错误,核心原因是**浏览器的同源策略(Same Origin Policy)**在起作用:

  • 当你直接在浏览器地址栏访问URL_SOURCE时,这属于浏览器发起的「普通导航请求」,浏览器不会触发CORS校验,所以能正常拿到JSON数据。
  • 但通过原生JavaScript的fetch发起请求时,这属于「跨域AJAX/Fetch请求」,浏览器会强制校验目标服务器返回的响应头,要求必须包含Access-Control-Allow-Origin字段,用来明确允许哪些域名的页面可以访问该资源。如果服务器没返回这个头,浏览器就会拦截请求,抛出你看到的错误。

另外顺便提一句,你的代码里还有个小bug:data变量是在fetch的回调里赋值的,但外面的if (data)判断会在fetch请求完成前执行,所以永远是undefined,根本走不到后续的逻辑。这个问题和CORS无关,但也是需要修正的点。

解决方案

针对CORS错误,你可以根据实际情况选择以下方案:

1. 配置目标服务器添加CORS响应头(最优解)

如果URL_SOURCE是你自己维护的服务器,直接在服务器端添加Access-Control-Allow-Origin响应头即可:

  • 允许所有域名访问:设置Access-Control-Allow-Origin: *
  • 仅允许你的静态页面域名访问:比如你的页面部署在https://your-static-page.com,就设置Access-Control-Allow-Origin: https://your-static-page.com

不同服务器的配置方式不同,比如Nginx、Apache、Node.js Express都有对应的配置方法,根据你的服务器类型调整即可。

2. 使用代理服务器中转请求(第三方API场景)

如果URL_SOURCE是第三方服务,你无法修改它的CORS配置,那可以自己搭建一个简单的代理服务器:

  • 代理服务器和你的静态页面同源(比如部署在同一个域名下)
  • 由代理服务器去请求URL_SOURCE,然后把响应返回给你的页面
  • 因为页面和代理服务器同源,就不会触发CORS校验

举个简单的Node.js代理示例(用express和http-proxy-middleware):

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();

app.use('/proxy', createProxyMiddleware({
  target: 'https://example.source.host',
  changeOrigin: true,
  pathRewrite: { '^/proxy': '' }
}));

app.listen(3000, () => console.log('Proxy server running on port 3000'));

然后你的前端代码里把URL_SOURCE改成http://localhost:3000/proxy即可。

3. 临时禁用浏览器CORS校验(仅开发测试用)

如果你只是在本地开发测试,可以临时关闭浏览器的CORS校验:

  • Chrome:启动时添加参数 chrome.exe --disable-web-security --user-data-dir="C:/ChromeDevSession"(注意路径自行调整)
  • Firefox:可以安装CORS相关的插件(比如CORS Everywhere)
    ⚠️ 注意:这个方法只能用于本地开发,绝对不能在生产环境使用,会带来安全风险。

修正你的代码异步问题

把原来的代码调整一下,把数据处理逻辑放到fetch的异步流程里,确保能拿到返回的数据:

const URL_SOURCE = 'https://example.source.host';
const doGetMetaDataEvent = async () => {
    setInterval(async () => {
        try {
            const response = await fetch(URL_SOURCE, {
                method: 'GET',
                headers: {
                    // some headers
                }
            });
            const data = await response.json();
            console.log('JSON response:', data);
            
            const nowData = data?.response?.informationjson?.getNowData;
            console.log('Listening to:', nowData?.songtitle);
        } catch (error) {
            console.error('Error data source or processing:', error);
        }
    }, 10000);
}

doGetMetaDataEvent()
.then(() => console.log("Render meta data successful"))
.catch(e => console.log('error response ', e.message));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 06:37:45