test-cors2 / app.js
viocha's picture
3
571c98a
raw
history blame
3.84 kB
import express from 'express';
import cors from 'cors';
const app = express();
const PORT = process.env.PORT || 7860;
// 'trust proxy' 在这个方案中不再是必需的,但保留它对于部署在反向代理后的应用仍是良好实践。
app.set('trust proxy', 1);
// --- CORS 配置 ---
// 保持之前的健壮配置
const corsOptions = {
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
exposedHeaders: ['X-Custom-Header-Test'],
credentials: false,
maxAge: 86400,
};
app.use(cors(corsOptions));
// --- 中间件和路由 ---
app.use((req, res, next) => {
res.setHeader('X-Custom-Header-Test', 'HuggingFace-Express-App-Works');
next();
});
app.get('/api', (req, res) => {
res.json({
message: 'API is working! CORS is correctly configured.',
timestamp: new Date().toISOString(),
});
});
// 根路由,返回一个静态 HTML 骨架,由客户端 JS 填充内容
app.get('/', (req, res) => {
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Express App on Hugging Face</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; line-height: 1.6; padding: 2em; background-color: #f9fafb; color: #111827; }
.container { max-width: 800px; margin: auto; background: white; padding: 2em; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.05); }
h1 { color: #1f2937; }
p { font-size: 1.1em; }
pre { background-color: #f3f4f6; padding: 1.5em; border-radius: 8px; white-space: pre-wrap; word-wrap: break-word; min-height: 150px; }
code { font-family: "Courier New", Courier, monospace; font-size: 1.1em; }
.copy-notice { font-size: 0.9em; color: #6b7280; margin-top: 1em; text-align: center; }
</style>
</head>
<body>
<div class="container">
<h1>Express.js 应用已部署</h1>
<p>请复制以下由浏览器动态生成的 <code>fetch</code> 代码到开发者工具中进行测试:</p>
<pre><code id="fetch-code"><!-- 代码将由 JS 动态填充于此 --></code></pre>
<p class="copy-notice">点击上面的代码块即可复制。</p>
</div>
<script>
// 在页面加载完成后执行
document.addEventListener('DOMContentLoaded', () => {
const codeElement = document.getElementById('fetch-code');
// 1. 由客户端 JS 直接、准确地获取 origin
const origin = window.location.origin;
// 2. 在客户端构建代码字符串
const fetchCode = \`fetch('\${origin}/api')
.then(response => {
console.log('Status:', response.status);
console.log('Content-Length:', response.headers.get('Content-Length'));
console.log('Custom Header "X-Custom-Header-Test":', response.headers.get('X-Custom-Header-Test'));
return response.json();
})
.then(data => console.log('Data:', data))
.catch(error => console.error('Error:', error));\`;
// 3. 将生成的代码注入到 HTML 中
codeElement.textContent = fetchCode;
});
// 复制功能保持不变
document.querySelector('pre').addEventListener('click', function() {
const codeToCopy = document.getElementById('fetch-code').innerText;
navigator.clipboard.writeText(codeToCopy).then(() => {
alert('代码已复制到剪贴板!');
}).catch(err => {
console.error('无法复制: ', err);
});
});
</script>
</body>
</html>
`);
});
app.listen(PORT, () => {
console.log(`Server is running at http://localhost:${PORT}`)
});