Vite + 通义千问文生图 前端完整实战教程
一、前言
现在通义千问提供了 qwen-image-2.0-pro 多模态生图接口,支持图生图、参考人物 + 参考服装 + 参考姿势融合生成图片。很多同学想直接在前端页面调用,但遇到几个痛点:
- 前端直接暴露 API Key 存在安全风险;
- 不懂 Vite 环境变量
import.meta.env配置; - 多模态接口入参格式、返回值解析踩坑;
- 从零搭建 Vite 原生 JS 项目流程不清晰。
本文完整从零搭建一个原生 Vite 纯 JS 项目,调用阿里通义文生图接口,实现传入 3 张参考图融合生成新图,并渲染到页面。
重要提醒:前端直接存放 API Key 仅适合本地调试、演示,线上生产环境必须后端中转接口,否则密钥会被抓包窃取,产生高额扣费。
二、环境与依赖说明
1. 技术栈
- Vite 8.x(原生 Vanilla JS,无框架)
- 原生
fetch发起 HTTP 请求,不引入 axios - 通义千问大模型多模态生图接口:
qwen-image-2.0-pro - Vite 内置环境变量,前缀
VITE_暴露给前端
2. package.json 依赖
仅开发依赖 Vite,无任何业务依赖:
json
{
"name": "qwen-image-demo",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"vite": "^8.0.12"
}
}
三、从零创建 Vite 项目步骤
1. 初始化项目
执行命令创建 vite 模板:
bash
运行
npm init vite
按照提示选择:
- Project name:
qwen-image-demo - Select a framework:
Vanilla(原生 JS,无 Vue/React) - Select a variant:
JavaScript
2. 进入项目安装依赖
bash
运行
cd qwen-image-demo
pnpm i
# 或 npm install
3. 新建环境变量文件 .env.local
项目根目录新建 .env.local 文件(git 忽略,不会提交密钥)
env
# .env.local
VITE_QWEN_API_KEY=sk-ws-H.REEHXDE.w45P.MEUCIQDRH56WtyOxiTUSVDkhpQQZ9NR8KGkrOIm0vDrIk0dVYwIgSM-Ajt0C8ichR49sEzAZJjUCyS5mWTySzZkxDDcIcs0
Vite 规则:只有以
VITE_开头的变量,才能在前端通过import.meta.env.xxx读取;.env.local本地生效,不会被打包上传,千万不要写在.env提交到代码仓库。
4. 配置 .gitignore(自动生成,无需手动)
Vite 模板自带忽略规则,关键一行:
plaintext
.env.local
保证密钥不会被提交 git。
四、完整代码实现
1. index.html 入口页面
html
预览
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>通义千问多模态图生图 Demo</title>
<style>
#app {
padding: 30px;
text-align: center;
}
img {
max-width: 100%;
width: 500px;
margin-top: 20px;
border-radius: 8px;
}
.tip {
color: #666;
}
</style>
</head>
<body>
<div id="app">
<h2>通义千问 多模态融合生图</h2>
<p class="tip">正在请求AI生成图片,请稍候...</p>
</div>
<!-- ES Module 脚本 -->
<script type="module" src="/src/main.js"></script>
</body>
</html>
2. src/main.js 业务逻辑(核心)
javascript
运行
// 读取Vite环境变量中的通义API密钥
const apiKey = import.meta.env.VITE_QWEN_API_KEY;
const root = document.querySelector('#app');
/**
* 调用通义千问多模态生图接口
* 参考3张图片:人物、服装、姿势,融合生成新图
*/
const generateImage = async () => {
// 校验密钥是否配置
if (!apiKey) {
root.innerHTML = '<p style="color:red">错误:请在.env.local配置VITE_QWEN_API_KEY</p>';
throw new Error("缺少API密钥");
}
const res = await fetch(
'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
// 鉴权Bearer Token
'Authorization': `Bearer ${apiKey}`,
},
body: JSON.stringify({
"model": "qwen-image-2.0-pro",
"input": {
"messages": [
{
"role": "user",
"content": [
// 参考图1:人物样貌
{ "image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250925/thtclx/input1.png" },
// 参考图2:黑色裙子服装
{ "image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250925/iclsnx/input2.png" },
// 参考图3:坐姿姿势
{ "image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250925/gborgw/input3.png" },
// 指令Prompt
{ "text": "图1的女生穿着图2中的黑色裙子按图3的姿势坐下,画面高清写实,光影自然" }
]
}
]
},
"parameters": {
"n": 1, // 生成1张图
"size": "1024*1536" // 图片尺寸
}
})
}
);
// 判断接口请求是否成功
if (!res.ok) {
const errData = await res.json();
root.innerHTML = `<p style="color:red">接口报错:${JSON.stringify(errData)}</p>`;
throw new Error(`请求失败:${res.status}`);
}
const data = await res.json();
console.log('AI返回完整数据', data);
// 取出生成图片地址
return data.output.choices[0].message.content[0].image;
};
/**
* 将生成的图片渲染到页面
* @param {string} imageUrl 图片在线地址
*/
const renderImage = (imageUrl) => {
root.innerHTML = `
<h2>AI生成完成</h2>
<img src="${imageUrl}" alt="AI生成图" />
`;
};
// 主执行函数
const main = async () => {
try {
const imageUrl = await generateImage();
renderImage(imageUrl);
} catch (err) {
console.error('生成失败:', err);
}
};
// 启动执行
main();
五、项目目录结构
plaintext
qwen-image-demo/
├── .env.local # 存放API密钥(不上传git)
├── .gitignore
├── index.html # 页面入口
├── package.json
├── package-lock.json # 依赖锁文件(你提供的lockfile)
└── src/
└── main.js # 核心业务代码
六、运行项目
bash
运行
# 启动开发服务
npm run dev
打开控制台输出的本地地址(http://localhost:5173),页面会自动请求 AI 接口,等待几秒渲染生成图片。
七、关键知识点详解
1. Vite 环境变量原理
- 后端 Node.js 使用
dotenv+process.env; - Vite 前端浏览器环境没有 process,提供
import.meta.env; - 变量必须以
VITE_为前缀,否则前端无法读取; .env.local本地私有,优先级高于.env,不会被打包进生产代码。
2. 通义多模态接口说明
- 请求地址:
dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation - 鉴权方式:
Authorization: Bearer {你的API_KEY} content数组支持混合多张图片 + 文本指令,实现人物、服装、姿势参考融合;- 返回值路径:
output.choices[0].message.content[0].image为生成图片 URL。
3. 安全重点(必看)
当前代码直接在前端携带 API Key 请求接口,存在严重安全缺陷:
- 浏览器网络面板可直接抓包拿到完整密钥;
- 任何人拿到密钥可无限调用你的通义模型,产生费用。
线上正确方案:后端中转
- 前端请求自己的后端服务;
- 后端存放密钥,由后端发起对通义接口的请求;
- 后端返回图片地址给前端,密钥全程不暴露浏览器。
八、常见踩坑解决
-
import.meta.env 读取不到密钥
- 变量名没有
VITE_前缀; - 修改
.env.local后没有重启npm run dev;
- 变量名没有
-
接口 401 鉴权失败
- API Key 复制错误、前后有空格;
-
跨域报错 CORS
- 阿里 dashscope 服务端不允许浏览器直接跨域,本地调试会出现跨域;
- 解决方案:本地配置 Vite 代理 / 后端中转(推荐);
-
返回数据路径报错 cannot read property 'image'
- 接口返回报错,没有 output 字段,先打印完整 data 查看错误信息。
九、拓展优化方向
- 增加加载状态、按钮手动触发生成(不要页面加载自动请求);
- 增加输入框自定义 Prompt、自定义图片尺寸;
- Vite 配置代理解决本地跨域;
- 封装后端 Node/Express 中转接口,隐藏 API 密钥;
- 增加图片下载、多图生成功能。
十、总结
本文基于 Vite 原生 JS 完成了通义千问多模态图生图完整 Demo,覆盖:
- Vite 项目创建、环境变量配置完整流程;
- 通义多模态接口入参、返回值解析实战;
- 前端直接调用大模型接口的优缺点与安全风险;
- 完整可运行代码 + 页面渲染逻辑。
适合新手学习 Vite 环境变量、前端调用 AI 大模型接口、多模态图生图基础实践。如果需要解决跨域、后端中转密钥的代码,可以告诉我,我补充配套 Node 后端示例。