js调用gpt3.5

news2025/1/22 16:00:33

参考链接:直接在前端调用 GPT-3 API

效果图:
在这里插入图片描述

小技巧:
1. shift+enter是发送消息的快捷键
2. 有本地聊天记录功能
3. 按delete按钮可以删除包括这条之后的记录


<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>ChatGPT Web Example</title>
  <style>
    body {
      font-family: "Helvetica Neue", Arial, sans-serif;
    }

    h1 {
      margin-bottom: 20px;
      text-align: center;
    }

    #chatbox {
      border: 1px solid gray;
      height: calc(100vh - 180px);
      margin-bottom: 20px;
      overflow-y: scroll;
      padding: 10px;
    }

    .message {
      margin-bottom: 10px;
      font-size: 18px;
    }

    pre {
      white-space: pre-wrap;
      word-wrap: break-word;
    }

    .user-message {
      color: forestgreen;
      text-align: right;
    }

    .assistant-message {
      color: darkolivegreen;
    }

    .warning-message {
      color: red;
    }

    .chatgpt-message {
      text-align: left;
    }

    #input-container {
      display: flex;
      align-items: center;
      justify-content: center;
      padding-right: 5%;
    }

    #inputbox {
      font-size: 1rem;
      margin-right: 10px;
      padding: 10px;
      width: 100%;
    }

    #submit {
      background-color: cornflowerblue;
      border: none;
      border-radius: 5px;
      box-sizing: border-box;
      color: white;
      cursor: pointer;
      float: right;
      padding: 10px 20px;
      width: 80px;
    }
  </style>
</head>

<body>
  <div id="chatbox">
    <!-- 消息列表 -->
  </div>
  <div id="input-container">
    <textarea id="inputbox" type="text" placeholder="请输入您的问题" rows="5"></textarea>
    <button id="submit" loading="true">提交</button>
  </div>
</body>
<script>
  /* 官方文档[https://platform.openai.com/docs/guides/chat] */
  const chatboxEl = document.getElementById("chatbox");
  const inputEl = document.getElementById("inputbox");
  const submitEl = document.getElementById("submit");

  const endpoint = "https://api.openai.com/v1/chat/completions"; //如api过时,请查询官网
  const apiKey = "sk-"; //换成自己的API Key
  const delayTime = 60000; // 超时时间为60秒
  const model = "gpt-3.5-turbo";
  const temperature = 1; // 回答随机度
  const max_tokens = 1000;
  const historyMessageNum = 10;
  let historyMessage = [];
  let messageIdx = 0;

  function addMessage(text, sender) {
    historyMessage.push({ role: sender, content: text });
    localStorage.setItem("localMessage", JSON.stringify(historyMessage));
    const messageEl = document.createElement("div");
    const preEl = document.createElement("pre");
    messageEl.classList.add("message");
    messageEl.classList.add(`${sender}-message`);
    preEl.textContent = text;
    messageEl.appendChild(preEl);
    if (sender == 'user') {
      const delEl = document.createElement("button");
      delEl.classList.add("delete");
      delEl.innerText = "delete";
      const nowIdx = (historyMessage.length - 1);
      delEl.onclick = function () {
        deleteMessage(nowIdx);
      };
      messageEl.appendChild(delEl);
    }
    chatboxEl.appendChild(messageEl);
    chatboxEl.scrollTop = chatboxEl.scrollHeight;
  }

  deleteMessage = (idx) => {
    const msgEls = document.querySelectorAll('.message');
    msgEls.forEach((el, i) => {
      if (i >= idx) {
        el.parentNode.removeChild(el);
      }
    })
    historyMessage = historyMessage.slice(0, idx);
    localStorage.setItem("localMessage", JSON.stringify(historyMessage));
  }

  async function getResponseFromAPI() {
    const controller = new AbortController();
    const signal = controller.signal;
    const timeout = setTimeout(() => {
      controller.abort();
    }, delayTime);
    const messages = historyMessage
      .filter((v) => ["system", "user", "assistant"].includes(v.role))
      .slice(-historyMessageNum); // 最近消息
    const response = await fetch(endpoint, {
      signal,
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        model,
        messages,
        max_tokens,
        n: 1,
        stop: null,
        temperature,
      }),
    });
    clearTimeout(timeout);
    const result = await response.json();
    return result.choices[0].message;
  }

  function init() {
    submitEl.addEventListener("click", async () => {
      const input = inputEl.value;
      addMessage(input, "user");
      inputEl.value = "";

      // 显示加载动画
      submitEl.innerHTML = "等待中...";
      submitEl.setAttribute("disabled", true);
      // 使用 OpenAI API 获取 ChatGPT 的回答
      getResponseFromAPI(input)
        .then((response) => {
          addMessage(response.content, response.role);
        })
        .catch((error) => {
          addMessage(
            error.name === "AbortError" ? "Network Error" : error.message,
            "warning"
          );
        })
        .finally(() => {
          // 隐藏加载动画
          submitEl.innerHTML = "提交";
          submitEl.removeAttribute("disabled");
        });
    });
    document.addEventListener("keydown", function (event) {
      if (event.shiftKey && event.keyCode === 13) {
        submitEl.click();
        event.preventDefault();
      }
    });
    const localMessage = localStorage.getItem("localMessage") ? JSON.parse(localStorage.getItem("localMessage")) : []
    chatboxEl.innerHTML = '';
    localMessage.forEach(v => addMessage(v.content, v.role));
  }

  init();
</script>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端插件库之vue3使用vue-codemirror插件

vue3插件vue-codemirror使用步骤和实例vue-codemirror使用配置说明:个人代码编辑区Demovue-codemirror 基于 CodeMirror &#xff0c;适用于 Vue 的 Web 代码编辑器。 使用 1.命令行安装 npm install vue-codemirror --save // cnpm install vue-codemirror --save如果运行…

vue3使用viewer

介绍 v-viewer是一款基于viewer.js的强大的插件&#xff0c;不但支持vue3版本&#xff0c;还支持vue2、JavaScript、jquery&#xff0c;有以下特点&#xff1a; 支持移动设备触摸事件支持响应式支持放大/缩小支持旋转&#xff08;类似微博的图片旋转&#xff09;支持水平/垂直…

idea / eclipse 配置 Tomcat 并发布 Web 项目

文章目录tomcat 安装配置简介下载安装系统环境配置优化配置修改默认内存管理员用户名和密码设置支持中文文件名称idea 配置 tomcat 并发布 web 项目项目创建为项目添加 tomcat发布测试eclipse 配置 tomcat 并发布 web 项目引入 tomcat建立 web 项目发布测试总结本篇内容主要讲述…

python Web开发 flask轻量级Web框架实战项目--实现功能--账号密码登录界面(连接数据库Mysql)

ps&#xff1a;各位好久不见&#xff0c;我回家了&#xff01;终于有时间把之前的一些东西整理一下了&#xff08;好吧&#xff0c;之前是我太懒了&#xff09;&#xff0c;今天分享一个功能简单的python web实战项目&#xff0c;后期功能可自行丰富。 先看效果 输入正确用户名…

猿创征文|【C++游戏引擎Easy2D】我拿吃零食的时间,学会了在C++上添加可点击按钮

&#x1f9db;‍♂️iecne个人主页&#xff1a;&#xff1a;iecne的学习日志 &#x1f4a1;每天关注iecne的作品&#xff0c;一起进步 &#x1f4aa;学C必看iecne 本文专栏&#xff1a;【C游戏引擎】. &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; ✨前…

vuex报错:Property or method “$store“ is not defined on the instance but referenced during render. Make

‘store’ is defined but never used no-unused-vars 最近在写vuex&#xff0c;报过一个这样的错误&#xff1a; Property or method “$store” is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the da…

结合表单验证谈el-form中model、prop、rules属性

目录前言modelproprules验证总结前言 最近写vue项目需要用element ui中的表单组件显示一些信息呈现在页面上&#xff0c;但在使用提供的一些属性时有些困惑——这三者之间有什么关系&#xff0c;必须要同时存在吗&#xff1f;于是在这里做一些记录。 model 官方说是表单中的数…

flex布局中使用flex-wrap实现换行

最近做个项目,其中有个样式是换行布局,作为样式渣渣的我一开始不会,只能查资料,然后摆平了它.今天得空了,简要记录一下,方便后面小伙伴布局使用. 参考资料 flex-wrap 开始样式 <div class"planWrap"><div class"content planItem">1</div…

vue 父传子 子传父实现方式

父传子&#xff1a; 主要步骤&#xff1a; 首先在子组件props中创建一个属性&#xff0c;用以接收父组件传过来的值&#xff1b;然后父组件中引用子组件&#xff0c;并在子组件标签中添加子组件props中创建的属性&#xff1b;最后把需要传给子组件的值赋给该属性。 理解&#…

Vue父子组件生命周期执行顺序

要想弄懂Vue父子组件的生命周期执行顺序&#xff0c;首先要知道vue页面的生命周期钩子函数的执行顺序&#xff0c;这也是在面试中老生常谈的问题&#xff0c;同时相信大家在工作的时候也能经常碰到父子组件加载上的问题&#xff0c;所以&#xff0c;不管是面试还是工作&#xf…

前端常见的时间转换方法合集+动态时钟效果实现

1.将时间戳转换为YYYY-MM-DD HH:mm:ss格式-老方法 通过对应的年月日时分秒依次进行拼接&#xff0c;另外还需要对小于10的值进行处理&#xff0c;在前面添加字符串‘0’&#xff0c;转换为常见的两位数时间格式 function transformTime(timestamp new Date()) { if (time…

Vue实现生成二维码

目 录 ①首先创建一个vue项目 ②引入qrcodejs2 ③封装组件 1. 创建Vue文件 2. 定义template模板 3. 引入QRCode包 4. 进行封装 5. less控制样式 ④启动项目 1. 在终端输入启动项目命令 2. 在浏览器中输入访问地址 3. 访问生成的二维码 4. 扫码进行解析 与后端用J…

CSS实现文字描边效果

一、介绍 最近在一个项目的宣传页中&#xff0c;设计师使用了文字描边效果&#xff0c;之前我确实没有实现过文字的描边效果&#xff0c;然后我在查阅资料后&#xff0c;知道了实现方法。文字描边分为两种&#xff1a;内外双描边和单外描边&#xff0c;也就是指在给文字加上描…

ElementPlus DateTimePicker日期时间选择器限制可选时间范围(精确时分秒)

项目场景 ElementPlus DateTimePicker日期时间选择器 当我们使用日期时间选择器时&#xff0c;可能会有需求只能选择今日之前或者今日之后&#xff0c;又或者一周内&#xff0c;一个月内的时间&#xff0c;而其他的时间应该禁止被用户选择。 解决 直接看文档&#xff1a; …

【element】el-autocomplete的常见用法

前言&#xff1a; 这段时间突然发现很少写博客了&#xff0c;平时都在平衡工作和休息的时间&#xff0c;周末也没动过笔&#xff0c;而且更重要的是我找不到写的内容了&#xff0c;在经历的初始的新知识的学习阶段后&#xff0c;目前的阶段更加转入对于业务的理解&#xff0c;…

vite基本配置教程

&#x1f469; 个人主页&#xff1a;不爱吃糖的程序媛 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域新星创作者、CSDN内容合伙人&#xff0c;专注于前端各领域技术&#xff0c;成长的路上共同学习共同进步&#xff0c;一起加油呀&#xff01; ✨系列专栏&#xff1a;前端…

C1认证之web基础知识及习题——我的学习笔记

文章目录 目录 文章目录 前言​​​​​​​ Web基础 十四、语义化标签 知识点 习题 十五、表单标签 知识点 习题 十六、转义字符 知识点 习题 十七、Head头 知识点 习题 十八、CSS引入方式 知识点 习题 十九、CSS背景 知识点 习题 二十、CSS文本属性 …

CSS合并单元格四种方式:table/display/flex/grid

目录 方式一&#xff1a;table【最简单写法】 方式二&#xff1a;display: table--不推荐 方式三&#xff1a;display: flex 方式四&#xff1a;display: grid 效果图&#xff1a; 方式一&#xff1a;table【最简单写法】 colspan&#xff1a;规定单元格可横跨的列数。row…

【vue2】近期bug收集与整理02

⭐【前言】 在使用vue2构建页面时候&#xff0c;博主遇到的问题难点以及最终的解决方案。 &#x1f973;博主&#xff1a;初映CY的前说(前端领域) &#x1f918;本文核心&#xff1a;博主遇到的问题与解决思路 目录⭐数据枚举文件的使用⭐elementUI中分页组件使用的注意事项⭐v…

vue解决Not allowed to load local resource

前言 在进行通过本地路径进行加载图片的时候&#xff0c;突然就报了这个问题 Not allowed to load local resource 这个是由于安全性的问题&#xff0c;导致浏览器禁止直接访问本地文件 那么&#xff0c;这边我说一下我具体是怎么解决的吧 问题描述 我的项目是用的vue的vant…