Access to fetch at 'https://fastly.picsum.photos/id/520/800/600.jpg?hmac=Yl8aFf9...

2025年09月26日 13:36 响应: 5.16秒 状态: success

🚨 错误信息

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 函数来代理请求。

    预防措施

  • 理解 CORS: 在进行跨域网络请求前,务必了解 CORS 的工作原理和限制。

  • 使用代理服务器: 对于需要跨域访问的第三方 API,尤其是在本地开发或需要处理敏感认证信息时,建议使用同源代理服务器来转发请求。