Access to fetch at 'https://fastly.picsum.photos/id/520/800/600.jpg?hmac=Yl8aFf9...
🚨 错误信息
Access to fetch at 'https://fastly.picsum.photos/id/520/800/600.jpg?hmac=Yl8aFf9eyZR6g4T6_N8giCen61Q2_iWBumgB_WuJeDM' (redirected from 'https://picsum.photos/800/600?random=1') from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
🤖 AI解决方案
Access to fetch at 'https://fastly.picsum.photos/id/520/800/600.jpg?hmac=Yl8aFf9eyZR6g4T6_N8giCen61Q2_iWBumgB_WuJeDM' (redirected from 'https://picsum.photos/800/600?random=1') from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
// 核心关键句翻译:
// 从源 'null' 访问 '...' (重定向自 '...') 的 fetch 被 CORS 策略阻止:请求的资源上没有 'Access-Control-Allow-Origin' 头部。
原因分析
浏览器安全策略(CORS)阻止了您的网页(源为 null,通常是本地文件访问)跨域请求 picsum.photos 的资源,因为服务器没有设置允许该源访问的 Access-Control-Allow-Origin 头部。
解决方案
由于 picsum.photos 是一个公共 API,通常不设置 Access-Control-Allow-Origin: null,因此直接从本地 null 源发起请求是无法解决的。您需要通过一个同源服务器来代理这个请求。
方法一:使用 Node.js/Express 作为代理
- 安装 Express:
npm install express cors
proxy.js): const express = require('express');
const cors = require('cors');
const fetch = require('node-fetch'); // 需要安装 node-fetch: npm install node-fetch
const app = express();
const port = 3001; // 选择一个未被占用的端口
app.use(cors()); // 允许所有域名的跨域请求 (在生产环境中请配置更严格的策略)
app.get('/proxy-picsum', async (req, res) => {
const imageUrl = req.query.url; // 从查询参数获取图片 URL
if (!imageUrl) {
return res.status(400).send('Missing URL parameter');
}
try {
const response = await fetch(imageUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const buffer = await response.buffer();
res.set('Content-Type', response.headers.get('content-type'));
res.send(buffer);
} catch (error) {
console.error('Error fetching image:', error);
res.status(500).send('Error fetching image');
}
});
app.listen(port, () => {
console.log(`Proxy server listening at http://localhost:${port}`);
});
node proxy.js
picsum.photos 的 URL 改为通过您的代理服务器: // 假设您的代理服务器运行在 http://localhost:3001
const imageUrl = 'https://picsum.photos/800/600?random=1';
const proxyUrl = `http://localhost:3001/proxy-picsum?url=${encodeURIComponent(imageUrl)}`;
fetch(proxyUrl)
.then(response => {
if (!response.ok) {
throw new Error(`Network response was not ok: ${response.statusText}`);
}
return response.blob(); // 获取图片数据
})
.then(blob => {
const imgElement = document.createElement('img');
imgElement.src = URL.createObjectURL(blob);
document.body.appendChild(imgElement); // 将图片添加到页面
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
方法二:使用浏览器的服务器(如 Live Server 扩展)
如果您使用的是 VS Code 的 Live Server 扩展,它会启动一个本地服务器。但 CORS 问题依然存在,因为 Live Server 本身不代理网络请求。需要采用上述代理方法。
方法三:部署到同源服务器
将您的前端代码部署到任何一个服务器上(例如 Netlify, Vercel, GitHub Pages 等),然后在后端设置一个 API Gateway 或 Lambda 函数来代理请求。
预防措施