使用OpenAI Image Variation API遇CORS错误,求Vanilla JS解决方案
解决OpenAI Image Variation API的CORS错误及图片提交方案
一、CORS错误的核心解决方案
浏览器同源策略禁止前端直接请求OpenAI API,必须通过后端代理转发请求。以下是完整的前后端实现:
1. 后端代理示例(Node.js/Express)
const express = require('express'); const fetch = require('node-fetch'); const cors = require('cors'); const app = express(); app.use(cors()); app.use(express.json({ limit: '5mb' })); // 适配base64数据的大小限制 app.post('/api/image-variations', async (req, res) => { try { const { image, n } = req.body; const openAIRes = await fetch('https://api.openai.com/v1/images/variations', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}` // 从环境变量读取密钥,禁止硬编码 }, body: JSON.stringify({ image: image.replace(/^data:image\/png;base64,/, ''), // 移除base64前缀 n: n || 4 }) }); const data = await openAIRes.json(); res.json(data); } catch (err) { res.status(500).json({ error: err.message }); } }); app.listen(3000, () => console.log('代理服务运行在端口3000'));
2. 前端Vanilla JS代码(修改后)
function requestImageVariation(image) { // image为Canvas导出的base64格式PNG // 前置校验 const imageSize = Math.round((image.length * 3) / 4 / 1024); // 计算base64对应的KB大小 if (imageSize > 4096) { console.error('图片大小不能超过4MB'); return; } if (!image.startsWith('data:image/png;base64,')) { console.error('必须提交PNG格式图片'); return; } const data = { image: image, n: 4 }; const options = { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }; // 请求自身后端代理,而非直接调用OpenAI API fetch("http://localhost:3000/api/image-variations", options) .then(res => res.json()) .then(res => console.log(res)) .catch(err => console.log(err)); }
二、图片类型说明
不需要更改图片类型,只要满足以下要求即可正常提交:
- 必须为PNG格式
- 图片尺寸为正方形(宽高相等)
- 文件大小不超过4MB
- 注意移除base64字符串的前缀(
data:image/png;base64,),上述后端代码已自动处理该步骤
三、其他图片提交方式
除了base64,还可以通过二进制Blob/File结合FormData提交,这种方式比base64节省约30%带宽:
前端代码示例(Blob/FormData方式)
async function requestImageVariationFromCanvas(canvas) { // 从Canvas获取PNG格式Blob const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); if (blob.size > 4 * 1024 * 1024) { console.error('图片大小不能超过4MB'); return; } const formData = new FormData(); formData.append('image', blob, 'source.png'); formData.append('n', 4); const options = { method: "POST", body: formData, }; fetch("http://localhost:3000/api/image-variations-form", options) .then(res => res.json()) .then(res => console.log(res)) .catch(err => console.log(err)); }
对应后端代理代码(处理FormData)
const multer = require('multer'); const upload = multer({ limits: { fileSize: 4 * 1024 * 1024 } }); // 限制文件大小4MB app.post('/api/image-variations-form', upload.single('image'), async (req, res) => { try { const { n } = req.body; const openAIRes = await fetch('https://api.openai.com/v1/images/variations', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}` }, body: new FormData(req) // 直接转发FormData }); const data = await openAIRes.json(); res.json(data); } catch (err) { res.status(500).json({ error: err.message }); } });
内容的提问来源于stack exchange,提问作者Bhuvanesh
相关产品推荐
相关产品推荐

