
目录
上一篇博文“十分钟教你部署一个属于自己的chatgpt网站”上了热榜收获了一千多收藏后,就有小伙伴问我有没有便宜一点的服务器,我一想这确实是个问题,即使买一个国内服务器,域名备案也很麻烦,基本需要一个月,而海外服务器价格又普遍比较高,对于我这种白嫖党来说,属实买不起!于是我便将我的gitee项目ChatGPT-website又改造了一个纯前端版本,以便于使用github pages或者gitee pages服务实现零成本部署!
Github Pages 是 github 公司提供的免费的静态网站托管服务,用起来方便而且功能强大,不仅没有空间限制,还可以绑定自己的域名。像现在很多人都用这个代码托管平台的Pages服务搭建自己的个人博客,一些门户网站之类的!
当然这里有个静态网站的概念很多人可能不太懂,粗略的说就是没有后端,不能动态交互数据(但借助 javascript 依旧可以实现交互性),即不能实时从后端获得数据在前端展示!这也就是我为啥将我的项目改一个纯前端版本了,Pages服务只能托管静态网站!
在看看更加标准的解释:
静态网站由存储在 Web 服务器上的固定数量的预构建文件组成。这些文件是用 HTML、CSS 和 JavaScript 编写的,它们被称为“客户端”语言,因为它们在用户的 Web 浏览器中执行。当用户使用 URL 向服务器请求页面时,服务器会返回由 URL 指定的 HTML 文件以及任何随附的 CSS 和/或 JavaScript 文件。在此交换期间,Web 服务器在将文件发送给用户之前不会更改文件,因此网页对于所有请求它的人来说都是完全相同的。内容是“静态的” — 改变网站外观的唯一方法是手动更改文件的内容。
这并不意味着静态网站不能具有交互性或吸引力。他们仍然可以拥有可点击的链接和按钮、图像和视频、表单、数字下载以及由 CSS或 JavaScript 提供支持的动画。有了足够的技巧,你甚至可以让静态网站看起来很漂亮。但是,静态网站对每个人来说总是一样的。
可以用GitHub Pages部署,也可以使用Gitee Pages,两者相比,Gitee pages速度更快点,但是Gitee Pages服务需要上传手持身份证照片,因此,这里我采用Github Pages部署!
项目地址:https://gitee.com/aniu-666/chat-gpt-website/tree/web/
拿走不谢,留下你的star!
纯前端版我放在了这个小项目(目前已有40star)的web分支,可以在网站点击下载按钮直接下载!

如果要使用git命令拉取,使用以下指令:
git clone -b web https://gitee.com/aniu-666/chat-gpt-website.git
拉取到本地后就可以将其上传到你的github进行pages部署了!
方式有很多,我先说普遍的创建仓库:

需要注意的是,要使用Pages服务,仓库状态必须要公开,私有是收费的!
创建仓库完成后可用git上传代码到仓库,也可直接在网站上传!

上传完成后按下图操作

可以看到你仓库的Pages服务已经好了,会生成一个网址,此时就可以访问啦!
当然访问网址一部分也是可以更改的!

这样创建仓库比较麻烦!
我在 github 也上传了一份,大家可以直接创建仓库时导入,也可直接fork一下,然后直接使用Pages服务就ok!
github仓库地址:https://github.com/Aniuyyds/ChatGPT-website
这样就实现了零成本部署,还有域名!
当然你可也开始用其他代码托管平台的Pages服务,像gitee,gitlab以及csdn的gitcode(这里我也拷贝了一份,进入gitcode找我这个账号昵称在我个人主页就可以看到)!
项目详情请看原gitee仓库地址!体验地址在gitee仓库里有,大家也可以填入自己的apiKey使用!
custom.js中部分代码
$.ajax({
url: 'https://open.aiproxy.xyz/v1/chat/completions',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + data.apiKey
},
data: JSON.stringify({
"messages": data.prompt,
"model": "gpt-3.5-turbo",
"max_tokens": 2048,
"temperature": 0.5,
"top_p": 1,
"n": 1
}),
success: function(res) {
const resp = res["choices"][0]["message"];
addMessage(resp.content,"chatgpt.png");
// 收到回复,让按钮可点击
chatBtn.attr('disabled',false)
// 重新绑定键盘事件
chatInput.on("keydown",handleEnter);
// 将回复添加到数组
messages.push(resp)
},
error: function(jqXHR, textStatus, errorThrown) {
addFailMessage('<span style="color:red;">' + '出错啦!请稍后再试!' + '</span>');
chatBtn.attr('disabled',false)
chatInput.on("keydown",handleEnter);
messages.pop() // 失败就让用户输入信息从数组删除
}
});
});
具体逻辑可以看仓库源码,注释很详细!
理论上只需在custom.js文件86行加入自己的 openai 的api key即可!

但是我不建议这么做,将apiKey直接写在静态文件中,基本上很容易暴露apiKey!这也是项目纯前端版本的缺点!
我曾想过将apiKey在本地加密后填写到custom.js文件中,然后解密,防止暴露,这确实能防止一部分人!但我也曾是一个爬虫爱好者,这种方式依旧没用,通过js逆向依旧能看到解密后的apiKey,因此我也取消了这个想法!所以我的建议是不填写这个apiKey,建议部署完成后,每次使用时在主页面填写apiKey,这样安全!

当然,本着安全的措施,我也加了几行几乎没用的代码:
// 禁用右键菜单
document.addEventListener('contextmenu',function(e){
e.preventDefault(); // 阻止默认事件
});
// 禁止键盘F12键
document.addEventListener('keydown',function(e){
if(e.key == 'F12'){
e.preventDefault(); // 如果按下键F12,阻止事件
}
});
这种禁止打开浏览器控制台的措施其实依旧没用,还是可以打开,具体什么方法我不说,感兴趣的可以去我的专栏硬泡javascrtipt中去找找,里面有一篇就是说这个的!

我曾见证了chatgpt的强大,也体验了New Bing,文心一言等众多AI产品,无不感叹时代的洪流是如此的强大,深深感叹自己的渺小,面对AI浪潮滚滚来袭,我们又该如何面对,出路又是什么?
最起码首先学会使用AI工具会是基本功,这里引用chatgpt官方的一句话:“抢走工作的不会是AI,而是率先掌握AI能力的人!”
【flask从入门到实战】专栏9.9火热订阅中,已包含两个项目,全站独一无二的脚手架搭建,直接复制简单无脑操作,项目结构类似Django,感兴趣的可以看看哦!
上一篇博文“十分钟教你部署一个属于自己的chatgpt网站”已收录到此专栏!
其他专栏请前往博主主页查看!
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
在Ruby中可以使用哪些替代方法来ping一个ip地址?标准库“ping”库的功能似乎非常有限。我对在这里滚动我自己的代码不感兴趣。有没有好的gem?我应该接受它并忍受它吗?(我在Linux上使用Ruby1.8.6编写代码) 最佳答案 net-ping值得一看。它允许TCPping(如标准rubyping),但也允许UDP、HTTP和ICMPping。ICMPping需要root权限,但其他则不需要。 关于ruby-Pingruby网站?,我们在StackOverflow上找到一个类
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir