当前位置: 首页 > news >正文

在线网站搭建系统网站是生成静态好还是动态好

在线网站搭建系统,网站是生成静态好还是动态好,网站建设的工作,网站 空间 双线近期参加的项目#xff0c;主管丢给我一个任务#xff0c;说要支持滑动验证码。我身为50岁的软件攻城狮#xff0c;当时正背着双手#xff0c;好像一个受训的保安似的#xff0c;中规中矩地参加每日站会#xff0c;心想滑动验证码在今时今日已经是标配了#xff0c;司空…近期参加的项目主管丢给我一个任务说要支持滑动验证码。我身为50岁的软件攻城狮当时正背着双手好像一个受训的保安似的中规中矩地参加每日站会心想滑动验证码在今时今日已经是标配了司空见惯想必网上一搜一大把岂非手到擒来。so easy妈妈再也不用担心我的工作与学习。 孰料在网上寻寻觅觅点点击击结果就是凄凄惨惨戚戚。好像提的最多的就是AJ-Captcha但居然貌似下线了文档打不开demo也不见。还有一个声称可能是最好的滑动验证码但好像很复杂并且日本少女漫画风跟我有代沟。有一个貌似跟Ant Design有点关联的组件叫Wetrial的好像还比较符合我的要求。但它只有前端没有给出后端实现并且它的前端好像也用不了。 但是这个Wetrial.SliderCaptcha阐述了从后端获得的数据仿佛制订了一个滑动验证码的接口标准。加上我在搜索过程中看到的一些具体提示有了一些思路。考虑到这个滑动验证不仅要给自己的web端使用还要开放给开发手机APP的外包人员调用因此需要可控、便利、清晰决定自己搞一个。 一、思路 1、背景图片和拼图图片都从后端以base64的方式返回给前端 2、一起返回给前端的是一个json对象包括背景和拼图内容、尺寸、token。token的作用是验证时即销毁避免重放攻击即每张背景图只验证一次 3、准备多张相同尺寸不同内容的背景图每次随机选一张 4、拼图从背景图中抠抠后的坑填上白色然后采集背景图的颜色生成噪点加入这个坑。为的是避免机器容易识别这个白坑。 在chapGPT的指导下历时一天终于搞了个demo。效果如下 滑动验证 二、后端 后端就2个接口一个供数据下载一个供验证。 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.web.bind.annotation.*;import javax.annotation.PostConstruct; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.*; import java.util.concurrent.TimeUnit;RestController public class CaptchaController {Autowiredprivate StringRedisTemplate redisTemplate;private String[] images;int puzzlePieceWidth 40;int puzzlePieceHeight 40;PostConstructpublic void init() throws IOException {PathMatchingResourcePatternResolver resolver new PathMatchingResourcePatternResolver();Resource[] resources resolver.getResources(classpath:/images/*.jpg); // 修改为 *.jpgimages new String[resources.length];for (int i 0; i resources.length; i) {images[i] resources[i].getURI().toString();}}GetMapping(/slideCaptcha)public MapString, Object getCaptcha() throws IOException {MapString, Object response new HashMap();// 生成唯一的 tokenString token UUID.randomUUID().toString();// 随机选择背景图像BufferedImage backgroundImage getBgImg();// 生成拼图块的随机位置int puzzlePieceLeft (int) (Math.random() * (backgroundImage.getWidth() - puzzlePieceWidth));int puzzlePieceTop (int) (Math.random() * (backgroundImage.getHeight() - puzzlePieceHeight));// 创建拼图块BufferedImage puzzlePieceImage new BufferedImage(puzzlePieceWidth, puzzlePieceHeight, BufferedImage.TYPE_INT_ARGB);Graphics2D puzzleG puzzlePieceImage.createGraphics();puzzleG.drawImage(backgroundImage, 0, 0, puzzlePieceWidth, puzzlePieceHeight, puzzlePieceLeft, puzzlePieceTop, puzzlePieceLeft puzzlePieceWidth, puzzlePieceTop puzzlePieceHeight, null);puzzleG.dispose();// 在背景图像上掩盖拼图块setMask(backgroundImage, puzzlePieceLeft, puzzlePieceTop);// 将图像转换为 Base64ByteArrayOutputStream baos new ByteArrayOutputStream();ImageIO.write(backgroundImage, jpg, baos); // 保持为 jpgString backgroundImageBase64 Base64.getEncoder().encodeToString(baos.toByteArray());baos.reset();ImageIO.write(puzzlePieceImage, png, baos); // 保持为 png 以支持透明度String puzzlePieceBase64 Base64.getEncoder().encodeToString(baos.toByteArray());// 缓存 token 和位置ValueOperationsString, String ops redisTemplate.opsForValue();ops.set(token, String.valueOf(puzzlePieceLeft), 5, TimeUnit.MINUTES);response.put(backgroundImage, backgroundImageBase64);response.put(puzzlePiece, puzzlePieceBase64);response.put(token, token);//response.put(puzzlePieceLeft, puzzlePieceLeft);//response.put(puzzlePieceTop, puzzlePieceTop);response.put(backgroundWidth, backgroundImage.getWidth());response.put(backgroundHeight, backgroundImage.getHeight());response.put(puzzlePieceWidth, puzzlePieceWidth);response.put(puzzlePieceHeight, puzzlePieceHeight);return response;}PostMapping(/slideVerify)public MapString, Object verifyCaptcha(HttpServletRequest request, RequestBody MapString, Object map) {MapString, Object response new HashMap();String token (String) map.get(token);int position (Integer) map.get(position);ValueOperationsString, String ops redisTemplate.opsForValue();String correctPositionStr ops.get(token);if (correctPositionStr ! null) {int correctPosition Integer.parseInt(correctPositionStr);if (Math.abs(position - correctPosition) 10) {response.put(success, true);} else {response.put(success, false);}redisTemplate.delete(token);} else {response.put(success, false);}return response;}private BufferedImage getBgImg() throws IOException {String selectedImage images[(int) (Math.random() * images.length)];PathMatchingResourcePatternResolver resolver new PathMatchingResourcePatternResolver();Resource resource resolver.getResource(selectedImage);InputStream inputStream resource.getInputStream();return ImageIO.read(inputStream);}private void setMask(BufferedImage backgroundImage, int puzzlePieceLeft, int puzzlePieceTop) {Graphics2D g backgroundImage.createGraphics();g.setComposite(AlphaComposite.Src);g.setColor(Color.WHITE); // 使用白色填充g.fillRect(puzzlePieceLeft, puzzlePieceTop, puzzlePieceWidth, puzzlePieceHeight);// 从整幅背景图像采集颜色Color[][] sampledColors new Color[backgroundImage.getWidth()][backgroundImage.getHeight()];for (int x 0; x backgroundImage.getWidth(); x) {for (int y 0; y backgroundImage.getHeight(); y) {sampledColors[x][y] new Color(backgroundImage.getRGB(x, y));}}for (int i puzzlePieceLeft; i puzzlePieceLeft puzzlePieceWidth; i) {for (int j puzzlePieceTop; j puzzlePieceTop puzzlePieceHeight; j) {// 获取背景区域的颜色Color noiseColor sampledColors[(int) (Math.random() * i)][(int) (Math.random() * j)];// 绘制扰乱元素g.setColor(noiseColor);g.fillRect(i, j, 1, 1); // 绘制单个像素点覆盖原始的白色矩形}}g.dispose();} }三、前端 demo使用经典的html js css来编写。注意请求后台的接口路径采用了nginx进行转发避免浏览器的跨域限制. !DOCTYPE html html langen headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleCaptcha Verification/titlestyle.captcha-container {position: relative;width: 367px;height: 267px;margin: 50px auto;border: 1px solid #ddd;background-color: #f3f3f3;}.background-image {position: absolute;top: 0;left: 0;width: 100%;height: 100%;}.puzzle-piece {position: absolute;width: 40px;height: 40px;cursor: move;box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* 添加阴影效果 */}.slider-container {width: 400px;margin: 20px auto;text-align: center;display: flex;align-items: center;justify-content: center;}.slider {width: 100%;-webkit-appearance: none; /* 去除默认样式 */appearance: none;height: 10px; /* 设置滑道高度 */background: #ddd; /* 滑道背景色 */border-radius: 5px; /* 圆角 */outline: none; /* 去除聚焦时的外边框 */transition: background .2s; /* 过渡效果 */}.slider::-webkit-slider-thumb {-webkit-appearance: none; /* 去除默认样式 */appearance: none;width: 20px; /* 滑块宽度 */height: 20px; /* 滑块高度 */background: #4CAF50; /* 滑块背景色 */border-radius: 50%; /* 圆形 */cursor: pointer; /* 光标样式 */box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); /* 滑块阴影效果 */}.refresh-btn {margin-left: 10px;padding: 8px 16px;cursor: pointer;background-color: #4CAF50;color: white;border: none;border-radius: 4px;font-size: 14px;}/style!-- Font Awesome CSS --link relstylesheet hrefhttps://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css /head bodydiv classcaptcha-containerimg idbackgroundImage classbackground-image src altBackground Imagediv idpuzzlePiece classpuzzle-piece/div/divdiv classslider-containerinput typerange min0 max327 value0 classslider idsliderbutton classrefresh-btn idrefreshBtni classfas fa-sync-alt/i/button/divscriptdocument.addEventListener(DOMContentLoaded, function() {let slider document.getElementById(slider);let puzzlePiece document.getElementById(puzzlePiece);let token ;function loadCaptcha() {fetch(/api/slideCaptcha) // 替换为你的后端接口地址.then(response response.json()).then(data {document.getElementById(backgroundImage).src data:image/jpeg;base64, data.backgroundImage;puzzlePiece.style.backgroundImage url(data:image/jpeg;base64, data.puzzlePiece );puzzlePiece.style.top data.puzzlePieceTop px;puzzlePiece.style.left 0px;token data.token;slider.value 0;}).catch(error console.error(Error fetching captcha:, error));}let refreshBtn document.getElementById(refreshBtn);refreshBtn.addEventListener(click, function() {loadCaptcha();});slider.addEventListener(input, function() {puzzlePiece.style.left slider.value px;});slider.addEventListener(change, function() {fetch(/api/slideVerify, { // 替换为你的后端验证接口地址method: POST,headers: {Content-Type: application/json,},body: JSON.stringify({token: token,position: parseInt(slider.value)}),}).then(response response.json()).then(data {if (data.success) {alert(:-) 验证成功);} else {alert(验证失败请重试);}loadCaptcha();}).catch(error console.error(Error verifying captcha:, error));});loadCaptcha();});/script /body /html 四、小结 俄国10月革命一声炮响送来了美国的chatGPT。chatGPT吧已经成了我的老师和工人。上面那些代码都是我提要求然后chatGPT生成的甚至包括注释。我只修改了极少的地方。功能的确强大。但它其实又还不够智能一些算法我一下子能看出问题需要重重复复地提要求每次它都说明白了。它输入了海量的资料知识渊博各种编程语法更是精通提交代码给它审查找问题最是合适不过。它一般也能按要求给出初始代码但有时总是差那么点意思。最讨厌的是问它一些社科历史类的问题经常一本正经地胡说八道。 这不是我想要的生活。 参考文章 SlideCaptcha - 滑动验证码 滑块验证 - 使用AJ-Captcha插件【超简单.jpg】 TIANAI-CAPTCHA
http://www.w-s-a.com/news/892747/

相关文章:

  • 外贸网站模板aspnet网站开发 视频
  • 上海植物租赁做网站南浔网站建设
  • 怎么做学校网站做兼职工作上哪个网站招聘
  • 软件下载网站哪个比较好杭州开发小程序
  • 做网站都用什么技术学做名片的网站
  • 备案网站忘记密码乐装网
  • 电商扶贫网站建设淄博网站建设小程序
  • 网站群建设代理丰城网站建设公司
  • 青岛网站建设服务器wordpress迁移跳转原网站
  • 泰安网站建设哪里有公司如何注册网站
  • 做网站开专票税钱是多少个点上海市有哪些公司
  • 寿县有做网站开发的吗宁波网站建设方式
  • 网站建设和网站推广服务器怎么发布网站
  • 比较好的摄影网站雅安市政建设公司网站
  • 网站与微信区别wordpress 站内信
  • 宁夏网站开发设计说明书源码下载脚本之家
  • 邱县做网站百度搜索排名机制
  • 运城个人网站建设智慧团建系统官方网站登录
  • 公司营业执照可以做几个网站一家专门做母婴的网站
  • 网站建设商标属于哪个类别搜狗seo快速排名公司
  • 织梦做商城网站企业网络建站
  • 网站后期维护都有什么wordpress首页加图片
  • 展会网站怎么做网页设计与制作教程版徐洪亮课后答案
  • 石景山网站建设设计公司建设网站怎么建立服务器
  • 本地生活服务平台app网站关键词优化原理
  • 建网站的公司叫什么重庆论坛建站模板
  • 湖北网站制作公司银川网站建设哪家不错
  • 网站后台演示地址服装网站建设公司推荐
  • 湖北钟祥建设局网站旅游哪个网站最好
  • 浙江建设工程信息网站辽宁建设工程信息网场内业绩什么意思