可行,但受同源策略和CORS限制;本地file://协议下fetch直接失败,须通过HTTP服务(如http://localhost:8000)运行页面,并使用支持CORS的API。

直接在 index.html 里用 fetch 调用 API 可行吗?
可行,但受同源策略和 CORS 限制——浏览器会拦截跨域请求,除非目标 API 明确允许你的页面域名(或返回 Access-Control-Allow-Origin: *)。本地双击打开 index.html(即用 file:// 协议)时,fetch 会直接失败,报错类似:Failed to fetch 或 CORS request not http。
实操建议:
- 必须通过 HTTP 服务访问页面:用
python3 -m http.server 8000、npx serve或 VS Code 的 Live Server 插件启动本地服务,让页面地址变成http://localhost:8000/index.html - 优先选支持 CORS 的公开测试 API,例如:
https://jsonplaceholder.typicode.com/posts/1 - 避免用 jQuery.ajax 或旧版
XMLHttpRequest——现代项目直接用fetch更轻量、可读性更强
fetch 基础写法 + 错误处理不能省
没加 catch 或没检查 response.ok,API 返回 404、500 时页面就静默失败,控制台也未必报错。以下是最小可用模板:
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.then(data => {
document.body.innerHTML = `<h2>${data.title}</h2><p>${data.body}</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p>`;
})
.catch(err => {
console.error('API 请求失败:', err);
document.body.innerHTML = '<p>加载失败,请检查网络</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill7761" title="Article To Html"><img
src="https://img.php.cn/upload/skill/000/000/081/179168408018805.jpg" alt="Article To Html" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill7761" title="Article To Html">Article To Html</a>
<p>文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。</p>
</div>
<a href="/xiazai/skill7761" title="Article To Html" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div>';
});
关键点:
-
response.json()本身也返回 Promise,必须用.then或await处理,否则得到的是 pending 状态的 Promise 对象 - 不要省略
if (!response.ok)判断——HTTP 状态码 4xx/5xx 不会进catch,只会进then - 避免在
fetch后直接操作 DOM 元素前未校验是否存在,比如document.getElementById('list').innerHTML = ...前应先确认该元素存在
需要发 POST 请求?注意 Content-Type 和 body 格式
GET 请求靠 URL 传参,POST 必须显式设置请求头并序列化数据。常见错误是忘记设 Content-Type,或把对象直接塞进 body 导致后端收不到字段。
正确写法示例(提交 JSON 数据):
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'hello',
body: 'world',
userId: 1
})
})
.then(r => r.json())
.then(console.log);
注意:
-
body必须是字符串、FormData或Blob,对象要先JSON.stringify - 如果后端只接受表单格式(
application/x-www-form-urlencoded),得手动拼接键值对:body: 'title=hello&body=world',或用new URLSearchParams({title:'hello'}).toString() - 某些 API(如 GitHub、Auth0)要求带
Authorization头,此时必须确保响应头中包含Access-Control-Allow-Headers: Authorization,否则浏览器预检(preflight)会失败
调试时怎么看请求是否发出、参数对不对?
别只盯着 JS 控制台,重点看浏览器开发者工具的 Network 选项卡:
- 刷新页面后,在
Network中找对应请求,点开看Headers里的Request URL、Request Method、Request Payload(POST)或Query String Parameters(GET) - 若请求根本没出现在列表里,说明 JS 报错了(比如语法错误、
fetch写错位置),或脚本没执行(<script>放在<body>底部但 DOM 尚未加载完) - 若状态码是
OPTIONS且失败,就是 CORS 预检被拒,需后端配置响应头;若是GET或POST直接 404/500,则检查 URL 和参数逻辑 - 临时验证 API 是否可用,可在终端用
curl模拟请求:curl -i https://jsonplaceholder.typicode.com/posts/1
CORS 和本地文件协议是硬门槛,绕不开;其他问题基本都能在 Network 和 Console 里定位。别在没开 DevTools 的情况下改代码。

















