AI全栈开发项目:使用DALL-E 3进行图像生成 | 前后端分离实战教程

释放双眼,带上耳机,听听看~!
学习如何利用Node.js驱动的DALL-E 3进行AI图像生成的全栈开发项目,包括配置开发环境、搭建前后端架构、与DALL-E 3 API交互,实现功能完备的图像生成应用。通过Bootstrap快速搭建前端界面,展示表单和图片生成功能。

引言

随着人工智能技术的迅猛发展,AI 在各个领域的应用变得越来越广泛和深入。在图像生成领域,OpenAI 推出的 DALL-E 系列模型,以其强大的图像生成能力和创新性,引起了广泛的关注和应用。DALL-E 3 作为这一系列的最新版本,能够根据文本描述生成高质量、复杂且创意无限的图像,为开发者提供了强大的工具。

今天呆同学和大家分享的是一个从前端到后端的 AI 全栈开发项目,具体内容是利用 Node.js 驱动的 DALL-E 3 进行 AI 图片生成。通过这次学习学会如何配置开发环境、搭建前后端架构、与 DALL-E 3 API 进行交互,并实现一个功能完备的图像生成应用。

AI全栈实战

今天这个项目我们将前后端分离的模式来进行,前端frontend文件和后端backend文件,那么接下来我们便开始吧。

frontend (前端)

图片:

AI全栈开发项目:使用DALL-E 3进行图像生成 | 前后端分离实战教程

html 部分

Bootstrap 引入

<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">

从 CDN 引入 Bootstrap 3.3.0 的 CSS 文件,提供预定义的样式和布局类。

页面布局

页面布局可以大体分为两个部分,一部分是表单内容,一部分是图片展示内容。其中,表单部分的布局我们通过Bootstrap实现一个快速搭建,也是十分重要的内容。它由一个图片名称的文本输入框、一个图片描述内容的多行问输入框和一个生成图片的按钮组成,点击按钮后通过按钮的提交事件触发请求,将用户输入的数据通过post请求发送给后端服务器。另一个部分则是在在后面拿到生成图片的URL,动态添加一个img标签展示图片

Bootstrap 是一个流行的前端框架,提供了一组预定义的 CSS 和 JavaScript 类,用于快速开发响应式和美观的网页。代码中使用了 Bootstrap 的 containerrowcol-md-6col-md-offset-3form-groupform-controlbtnbtn-primary 类,来实现布局和样式。

<!-- bootstrap 框架 -->
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <form name="logoForm">
                    <div class="form-group">
                        <label for="titleInput">Bot名称</label>
                        <input type="text" class="form-control" id="titleInput" name="title" placeholder="请输入Bot名称"
                            required>
                    </div>
                    <div class="form-group">
                        <label for="descInput">Bot介绍</label>
                        <textarea class="form-control" name="desc" id="descInput" placeholder="请输入Bot介绍"></textarea>
                    </div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-primary">生成图标</button>
                    </div>
                </form>
            </div>
            <div class="row" id="logo">

            </div>
        </div>
    </div>

1. Bootstrap 网格系统

  • <div class="container">:Bootstrap 的容器类,包含所有内容并提供固定宽度和响应式行为。

  • <div class="row">:Bootstrap 的行类,用于创建水平布局。

  • <div class="col-md-6 col-md-offset-3">:Bootstrap 的列类,设置宽度为 6 列(中等屏幕),并在左侧偏移 3 列,使表单居中。

2. 表单元素

  • <div class="form-group">:Bootstrap 的表单组类,提供样式和间距。

  • <label for="titleInput"><label for="descInput">:输入字段的标签。

  • <input type="text" class="form-control" id="titleInput" name="title" placeholder="请输入Bot名称" required>:文本输入框,使用 Bootstrap 的 form-control 类。

  • <textarea class="form-control" name="desc" id="descInput" placeholder="请输入Bot介绍"></textarea>:文本区域,使用 Bootstrap 的 form-control 类。

  • <button type="submit" class="btn btn-primary">生成图片</button>:提交按钮,使用 Bootstrap 的 btnbtn-primary 类,提供按钮样式。

JavaScript 部分

1. 获取表单和图标容器

const oForm = document.forms['logoForm'];
const oLogo = document.getElementById('logo');

获取所有表单元素和图标容器,用于获取用户输入的信息和设置监听提交事件的监听器。

2. 表单提交事件监听

oForm.addEventListener('submit', function (e) {
    e.preventDefault(); // 阻止默认提交行为
    const title = this["title"].value.trim(); // 获取并去除标题输入框的首尾空格
    const desc = this["desc"].value.trim(); // 获取并去除介绍输入框的首尾空格

在监听提交事件的监听器中,需要阻止默认的页面刷新行为,this在这里引用的是表单oForm,this["title"].valuethis["desc"].value 访问的是表单中 name 属性分别为 titledesc 的输入值。

3. 检查数据并整理数据

if (title) {
    const data = {
        title,
        desc
    }

在发送请求之前,我们先检查一下是否有值,如果有则继续处理数据

4. 发送数据到服务器

// post 提交表单
 fetch('http://localhost:3000/logo', {
   method: 'POST',
   // 请求体 字符串或文件二进制
   body: JSON.stringify(data), // 对象转字符串
   headers: {
       'Content-Type': 'application/json' // 表示发送的是json数据
     }
  })
     .then(res => res.json())

提交表单数据,使用Fetch API 向服务器发送 POST 请求,然后将 data 对象转换为 JSON 字符串,并作为请求体发送。设置请求头,表示请求体的内容类型为 JSON。最后解析服务器响应为 JSON 格式。

5. 处理服务器响应

    .then(data => {
        if (data.code == 200) { // 检查响应代码
           const { url } = data; // 获取生成的图标 URL
           const oImag = document.createElement('img'); // 创建图像元素
           oImag.src = url; // 设置图像源
           oImag.onload = function () { // 图像加载完成后
                document.getElementById('logo').appendChild(oImag); // 将图像添加到页面
            }
         } else {
            console.log('出错了'); // 错误处理
            }
        })
    }
});

处理解析后的 JSON 数据,先检查响应中的code是否为 200,是则表示请求成功,然后从响应数据中提取出url属性,即生成的图片的 URL,再创建一个新的图片标签,设置图像的src属性为生成的图片的 URL,最后在图像加载完后,执��函数,将图片渲染在页面上id="logo" 的容器中。

完整前端代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
    <style>
        #logo img {
            display: block;
            width: 200px;
            height: 200px;
        }
    </style>
</head>

<body>
    <!-- bootstrap 框架 -->
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <form name="logoForm">
                    <div class="form-group">
                        <label for="titleInput">Bot名称</label>
                        <input type="text" class="form-control" id="titleInput" name="title" placeholder="请输入Bot名称"
                            required>
                    </div>
                    <div class="form-group">
                        <label for="descInput">Bot介绍</label>
                        <textarea class="form-control" name="desc" id="descInput" placeholder="请输入Bot介绍"></textarea>
                    </div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-primary">生成图标</button>
                    </div>
                </form>
            </div>
            <div class="row" id="logo">

            </div>
        </div>
    </div>

    <script>
        const oForm = document.forms['logoForm'];
        const oLogo = document.getElementById('logo');

        oForm.addEventListener('submit', function (e) {
            e.preventDefault();
            const title = this["title"].value.trim();
            const desc = this["desc"].value.trim();
            // console.log(title, desc, '///');
            if (title) {
                const data = {
                    title,
                    desc
                }
                // post 提交表单
                fetch('http://localhost:3000/logo', {
                    method: 'POST',
                    // 请求体 字符串或文件二进制
                    body: JSON.stringify(data), // 对象转字符串
                    headers: {
                        'Content-Type': 'application/json' // 表示发送的是json数据
                    }
                })
                    .then(res => res.json())
                    .then(data => {
                        // console.log(data);
                        if (data.code == 200) {
                            const { url } = data;
                            const oImag = document.createElement('img');
                            oImag.src = url;
                            oImag.onload = function () {
                                document.getElementById('logo').appendChild(oImag);
                            }
                        } else {
                            console.log('出错了');
                        }
                    })
            }
        });
    </script>
</body>
</html>

backend (后端 + OpenAI)

接下来便开始用 Node.js 搭建我们的后端,在后端中我将引入 OpenAI 的服务。

初始化项目

首先初始化一个Node.js后端项目

npm init -y

安装模块

安装项目所需模块

npm i koa
npm i koa-router
npm i @koa/cors
npm i -g nodemon
npm i @koa/bodyparser
npm i openai
npm i dotenv

一起来看看每个模块的作用吧:

  1. koa 是一个用于构建 Web 应用程序和 API 的新型 Web 框架, 基于中间件的架构,使得处理 HTTP 请求和响应更灵活。使用现代 JavaScript 特性,如 asyncawait,编写异步代码更简单。旨在提供更强大的中间件功能,处理 HTTP 请求和响应的流更简洁。

  2. Koa Router 是一个为 Koa 提供路由功能的中间件,使得定义和组织路由更加方便。作用是定义不同的 HTTP 方法(如 GET、POST)的路由。组织和管理路由,使代码更清晰和可维护。

  3. @koa/cors 是一个 Koa 的中间件,用于处理跨域资源共享(CORS)。作用是允许服务器接受来自不同源(域)的请求,解决浏览器的同源策略限制。可以配置允许的来源、HTTP 方法、请求头等。

  4. Nodemon 是一个开发工具,用于在检测到文件变更时自动重启 Node.js 应用程序。作用是提高开发效率,自动检测代码变更并重启服务器,这样避免了代码更新后重新启动node服务。支持多种文件类型的监控,如 .js, .json, .md 等。

  5. @koa/bodyparser 是一个 Koa 中间件,用于解析请求体中的数据,支持 JSON 和 URL-encoded 格式。
    作用是自动解析请求体数据,并将解析后的数据绑定到 ctx.request.body 上。支持多种格式,如 JSON、表单数据等。

  6. OpenAI 是一个 SDK,用于与 OpenAI 的 API 进行交互,如 DALL-E、GPT-3 等。作用是提供与 OpenAI API 的接口,便于开发者集成和使用 OpenAI 的各项服务。支持文本生成、图像生成、代码生成等多种功能。

  7. Dotenv 是一个模块,用于将环境变量从 .env 文件加载到 process.env 中。作用是使得在开发过程中管理环境变量更方便和安全。支持将敏感信息(如 API 密钥)存储在 .env 文件中,避免硬编码到代码中。

中间件(Middleware)是指在请求处理过程中,被用来执行一系列任务的软件。它介于客户端请求和服务器响应之间,负责处理、修改、或管理请求和响应。

在 Web 开发中,中间件通常用于:

  1. 请求预处理:在请求到达实际路由处理器之前,对请求进行检查或修改。例如,验证用户身份、解析请求体、添加 CORS 头等。
  2. 响应后处理:在响应返回客户端之前,对响应进行检查或修改。例如,格式化响应数据、压缩响应等。
  3. 日志记录:记录请求和响应的信息,用于调试和监控。
  4. 错误处理:捕获并处理请求处理过程中的错误。

在 Koa 中使用中间件

Koa 框架通过其简洁的中间件机制提供了强大的扩展能力。Koa 中的中间件是一个函数,它接收两个参数 ctx(上下文)和 next(调用下一个中间件的函数)。中间件的执行顺序是按定义顺序进行的,形成一个中间件栈。

导入模块

我们将安装好的模块导入,导入我们通过 ES6 模块使用import导入,后面用export导出。

import Koa from 'koa';
import Router from 'koa-router';
import cors from '@koa/cors';
import { bodyParser } from '@koa/bodyparser';
import OpenAI from 'openai';
import dotenv from 'dotenv';

获取 API Key

想要调用 OpenAI 的服务必须要有 API Key,没有的话可以去任何一个代理处获取一个,这里提供一个代理处:WildCard,选择 “API 随心用” 这一栏,接下来便是要充值了,充值完后就会得到自己的 API Key。要注意的是,这个 Key 要保存好,不要泄露,否则别人用的话会扣钱的,说多了都是泪啊。

然后就在创建好的.env文件中存储你的 API key。

OPENAI_KEY='你的API Key'

配置环境变量

dotenv.config({
  path: '.env'
});

加载 .env 文件中的环境变量,使其可以通过 process.env 访问。

配置 OpenAI 客户端

const client = new OpenAI({
  apiKey: process.env.OPENAI_KEY,
  baseURL: 'https://api.gptsapi.net/v1'
});

创建 OpenAI 客户端实例client,使用从环境变量中加载的 API 密钥,并通过baseURL这个代理间接访问 OpenAI 的 API 服务。

创建 Koa 应用

const app = new Koa();
const router = new Router();

使用 Koa 框架和 Koa-Router 中间件分别创建 Koa 应用实例和 Koa-Router 实例。有了 Koa 框架和路由系统,后续我们就可以定义和操作路由。

使用中间件

// 挂载跨域功能
app.use(cors());
// 挂载post请求体解析功能
app.use(bodyParser());
  • app.use(cors()):使用跨域中间件,允许跨域请求。

  • app.use(bodyParser()):使用请求体解析中间件,解析 JSON 请求体。

定义路由

router.post('/logo', async (ctx) => {
  const { title, desc } = ctx.request.body;
  const prompt = `
    你是一位举世闻名的美术设计师,请为图片名为${title},
    描述细节为${desc}的内容
    设计一张符合图片名和描述细节的高质量图片
  `;

  try {
    const response = await client.images.generate({
      model: "dall-e-3",
      prompt: prompt,
      n: 1,
      size: "1024x1024",
    });

    ctx.body = {
      code: 200,
      url: response.data[0].url
    };
  } catch (error) {
    console.error(error);
    ctx.body = {
      code: 500,
      msg: '出错了'
    };
  }
});

router.get('/', (ctx) => {
  ctx.body = 'index page';
});
  • 定义一个处理/logo路径的 POST 请求的路由和一个处理函数,用于接收表单数据并调用 OpenAI API 生成图片。

    • 从请求体中提取 titledesc
    • 构建 prompt 字符串,用于生成图片。
    • 调用 OpenAI API 的 dall-e-3 接口,通过images.generate() 方法生成图片。
    • 将生成的图片 URL 返回给客户端。
  • 再定义 GET 路由,在用户访问根路径http://localhost:3000/时返回一个响应,设置响应体为 index page,这意味着服务器会返回一个简单的文本响应 ” index page “, 这段简单的路由可以用于调试和测试,确保服务器和路由配置正确。。

使用路由中间件并启动服务

// router.routes 路由上的所有路由的声明加上去
app.use(router.routes());

// http 服务 端口号 3000
app.listen(3000, () => {
  console.log('server is running at http://localhost:3000');
});
  • 将路由中间件添加到 Koa 应用中,使其生效。
  • 启动服务器,监听 3000 端口,并输出提示信息。

注意:前端和后端定义的路径和方法需要保持一致,以确保前端请求能够正确地到达后端,并得到期望的响应。

一致性检查

  1. 请求方法:前端使用 fetch 方法发送 method: POST 请求,而后端也定义了一个 POST 路由来处理该请求。二者保持一致。
  2. 请求路径:前端请求的路径是 http://localhost:3000/logo,后端定义的路由路径是 /logo。二者保持一致。

如果路径或请求方法不一致,前端请求将无法正确到达后端。例如:

  • 如果前端使用 fetch('http://localhost:3000/logo') 而后端定义了 router.post('/logos'),则前端请求不会匹配到后端的路由。
  • 如果前端使用 method: 'GET' 而后端定义了 router.post('/logo'),同样会导致请求无法匹配到正确的路由。

效果展示

AI全栈开发项目:使用DALL-E 3进行图像生成 | 前后端分离实战教程

总结

今天的学习内容涉及前后端的协调与整合,特别是在构建一个基于 Node.js 和 Koa 框架的后端服务,同时通过前端与其交互,完成特定任务的实现。以下是今天学习的总结:

  1. 前端与后端路径和方法一致性:学会了如何确保前端发起的请求与后端定义的路由保持一致,这是前后端交互的基础。
  2. Koa 框架的使用:深入了解了 Koa 框架的基本使用,包括如何创建 Koa 应用、定义路由、使用中间件处理请求和响应、以及启动服务器。掌握了跨域处理(@koa/cors)和请求体解析(@koa/bodyparser)的基本操作。
  3. 环境变量管理:学习了使用 dotenv 管理环境变量的方法,确保敏感信息(如 API 密钥)不被硬编码在代码中,提升了应用的安全性和灵活性。
  4. 调用 OpenAI API:通过实例了解了如何使用 OpenAI SDK 调用 DALL-E 3 模型,根据用户输入生成高质量的图片。学会了处理异步请求和错误处理的基本方法。
  5. 前端表单处理:学会了如何在前端使用 fetch API 发送 POST 请求,如何获取表单数据、发送 JSON 数据,以及处理响应。
  6. 调试和测试:理解了在开发过程中如何通过简单的 GET 路由进行调试和测试,以确保服务器和路由配置正确。

通过这些学习,你已经掌握了构建一个前后端协作的基础知识,能够创建一个基本的 Web 应用,实现从用户输入到后端处理再到结果展示的完整流程。这些技能将为你未来开发更复杂的应用奠定坚实的基础。继续加油!

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

AI工作流搭建教程:用Coze快速创建购车Agent

2024-8-10 20:55:00

AI教程

MLLM视觉模型选择及评估研究

2024-8-11 18:04:00

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索