如何从本地静态HTML页面调用Express(Node.js) API?
这个问题的核心在于直接双击打开的HTML页面使用的是file://协议,而你的Express服务运行在http://localhost:8080(HTTP协议),浏览器的同源策略会阻止跨协议的请求,而且file://协议本身对AJAX请求有严格的安全限制。下面给你两种可行的解决办法,优先推荐第一种生产/开发通用的方案:
方案一:将静态页面托管到Express服务器(推荐)
把你的hello.html放到Express服务的静态文件目录下,让页面和API同源,这样就不会有跨域问题了,步骤如下:
1. 整理项目结构
调整你的文件结构,把静态页面放到一个专门的目录(比如public):
你的项目文件夹/ ├── server.js # 你的Express服务文件 └── public/ └── hello.html # 你的静态HTML页面
2. 修改Express代码,添加静态文件托管
在你的server.js里,添加express.static中间件,用来托管public目录下的静态文件:
const express = require('express'); const app = express(); const port = 8080; // 新增:托管public目录下的静态文件 app.use(express.static('public')); // 你的现有API接口 app.get('/api/ls', (req, res) => { // 这里是你执行类似ls操作的代码,比如返回文件列表 res.json({ files: ['file1.txt', 'file2.js'] }); }); app.listen(port, () => { console.log(`服务器运行在 http://localhost:${port}`); });
3. 访问页面并测试API
启动你的Express服务器后,在浏览器地址栏输入 http://localhost:8080/hello.html 打开页面,此时页面和API处于同一个源(都是http://localhost:8080),就可以正常调用API了。
页面调用API的示例代码
在hello.html里添加调用API的脚本(以原生fetch为例):
<!DOCTYPE html> <html> <head> <title>Hello Page</title> </head> <body> <h1>Hello World</h1> <div id="api-result"></div> <script> // 页面加载完成后调用API document.addEventListener('DOMContentLoaded', async () => { try { // 调用你的API接口,同源下直接写相对路径即可 const response = await fetch('/api/ls'); if (!response.ok) { throw new Error(`HTTP错误!状态码:${response.status}`); } const data = await response.json(); // 把结果渲染到页面上 const resultDiv = document.getElementById('api-result'); resultDiv.innerHTML = `<h3>API返回的文件列表:</h3><ul>${data.files.map(file => `<li>${file}</li>`).join('')}</ul>`; } catch (error) { console.error('调用API失败:', error); document.getElementById('api-result').textContent = `调用API出错:${error.message}`; } }); </script> </body> </html>
方案二:临时关闭浏览器同源策略(仅用于开发测试)
如果你只是临时测试,不想修改项目结构,可以通过启动浏览器时关闭同源策略的方式绕过限制,但这个方法非常不安全,只能用于本地开发测试,绝对不能用于生产环境:
Chrome浏览器(Windows)
在桌面创建Chrome的快捷方式,右键点击快捷方式→属性→在“目标”栏的末尾添加以下参数(注意前面加空格):
--disable-web-security --user-data-dir="C:/ChromeDevSession"
然后双击这个快捷方式打开Chrome,再双击hello.html,就可以调用http://localhost:8080的API了。
Chrome浏览器(Mac)
打开终端,执行以下命令:
open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --disable-web-security --user-data-dir="/tmp/chrome_dev_test"
这个命令会打开一个新的Chrome窗口,在这个窗口里打开hello.html即可正常调用API。
内容的提问来源于stack exchange,提问作者ffConundrums

