Nuxt3调用Stable Diffusion API遇CORS错误,求解决方案
问题描述
我用Nuxt3开发,基于Stable Diffusion API官方文档编写Vue代码,实现点击img标签后将其src替换为API返回的图片,但一直触发CORS错误:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://stablediffusionapi.com/api/v3/text2img. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 301.
Postman测试相同参数可正常运行,但前端修改请求头、更换浏览器、改用Axios等方法均无效。我的代码如下:
<template> <img id="hot" @click="wee()" style="width:1000px;height:1000px;border:solid;"> </template> <script> import axios from 'axios'; function w(){ console.log("dsa"); } export default { methods: { async wee(){ console.log("start"); var myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); myHeaders.append("Access-Control-Allow-Origin", "*"); myHeaders.append("Access-Control-Allow-Headers", "Content-Type"); myHeaders.append("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); var raw = JSON.stringify({ "key": "THE KEY", "prompt": "ultra realistic close up portrait ((beautiful pale cyberpunk female with heavy black eyeliner))", "negative_prompt": null, "width": "512", "height": "512", "samples": "1", "num_inference_steps": "20", "seed": null, "guidance_scale": 7.5, "safety_checker": "yes", "multi_lingual": "no", "panorama": "no", "self_attention": "no", "upscale": "no", "embeddings_model": "embeddings_model_id", "webhook": null, "track_id": null }); var requestOptions = { method: 'POST', headers: myHeaders, body: raw, redirect: 'follow' }; var stuff =axios.post("http://stablediffusionapi.com/api/v3/text2img", requestOptions) .then(response => response.text()) .then(result => console.log(result)) .catch(error => console.log('error', error)); document.getElementById("hot").src = stuff; } } } </script>
解决方法
1. 修正API请求地址(解决301重定向问题)
错误提示中的301状态码表明原HTTP地址需要重定向到HTTPS,将请求地址从http://stablediffusionapi.com/api/v3/text2img改为https://stablediffusionapi.com/api/v3/text2img,绝大多数公开API仅支持HTTPS协议,HTTP请求会触发重定向导致CORS验证失败。
2. 移除前端无效的CORS响应头
你在请求头中添加的Access-Control-Allow-Origin、Access-Control-Allow-Headers等字段属于服务器返回给浏览器的响应头,前端请求时添加这些字段完全无效,反而可能干扰请求逻辑,直接删除以下代码:
// 删除这几行 myHeaders.append("Access-Control-Allow-Origin", "*"); myHeaders.append("Access-Control-Allow-Headers", "Content-Type"); myHeaders.append("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
3. 启用Nuxt3代理绕过浏览器CORS限制
浏览器的同源策略会拦截前端跨域请求,Postman不受限制是因为它非浏览器环境。利用Nuxt3自带的代理功能,将请求转发到服务器端,绕过浏览器的CORS检查:
- 安装代理模块:
npm install @nuxtjs/proxy
- 在
nuxt.config.ts中配置代理:
export default defineNuxtConfig({ modules: ['@nuxtjs/proxy'], proxy: { '/api/sd': { target: 'https://stablediffusionapi.com/api/v3', changeOrigin: true, pathRewrite: { '^/api/sd': '' } } } })
- 修改前端请求地址为代理路径:
// 将原axios请求替换为代理地址 const response = await axios.post('/api/sd/text2img', payload, { headers: { 'Content-Type': 'application/json' } })
4. 修正异步请求的处理逻辑
你直接将axios.post()返回的Promise赋值给stuff并设置为img的src,这是错误的——Promise不是图片URL。需要等待请求完成后,从API返回结果中提取图片地址:
async wee(){ console.log("start"); try { const payload = { "key": "THE KEY", "prompt": "ultra realistic close up portrait ((beautiful pale cyberpunk female with heavy black eyeliner))", "negative_prompt": null, "width": "512", "height": "512", "samples": "1", "num_inference_steps": "20", "seed": null, "guidance_scale": 7.5, "safety_checker": "yes", "multi_lingual": "no", "panorama": "no", "self_attention": "no", "upscale": "no", "embeddings_model": "embeddings_model_id", "webhook": null, "track_id": null }; const response = await axios.post('/api/sd/text2img', payload, { headers: { 'Content-Type': 'application/json' } }); // 参考Stable Diffusion API返回格式,图片URL通常在output数组中 const imageUrl = response.data.output[0]; document.getElementById("hot").src = imageUrl; } catch (error) { console.log('error', error); } }
内容的提问来源于stack exchange,提问作者Daniel Awoke

