在设计和实现的过程之后,你永远不知道部署上去的程序会已什么样的姿势运行。
本篇借一次生成二维码逻辑的不同实现,阐述 Web 项目中二维码生成的正确姿势。
文中如有批量,欢迎各位看客老爷拍砖。试运行前5天实现的逻辑是这样的:
- 客户 ajax 请求生成二维码,后端服务洞悉这一请求,生成二维码(可参照我博客:Google Zxing 二维码生成与解析)。
- 并将二维码已用户 ID 进行命名存储在项目工程 /webcontent/qrcode/AAAAAAAAAAAAAA.png 当中。
- 使用用户 ID 是想减少服务器存储压力,一个用户有且只有一张二维码,无论他点击了多少次,项目目录下只保存一张(Java IO 会在写文件前判断,如果存在相同名称的文件,会直接覆盖)。
- 将生成的 二维码 名称返回给前端,Jquery 将图片路径属性精准的放入 Dom 元素中。
var qrcode = $("#qrcode"); qrcode.removeAttr("src"); qrcode.attr("src","${pageContext.request.contextPath}/qrcode/" + data.qrcodeFileName);
实现后出现的问题:
- 当用户在一个业务点击了多次生成二维码时,因为有时效性,导致后续生成的二维码都失效,一边点马上扫都会是失效。
- 查看日志发现,后续的请求链接都是第一次生成的时间戳,查看项目目录发现,二维码确实是实时生成,但扫码后的链接却是第一次的。
- 我想问题应该在浏览器上面,经过反复实验,几乎所有的浏览器在第一次引入相同路径相同名称的图片时,后续如果还需要引入,会读取浏览器缓存当中的图片。
- 你不可能对用户说“每次点生成二维码的时候先清除一下你的浏览器缓存图片”,对吧?。
- 其实项目目录下的图片内容已经发生变化,只是名称和引入路径没变,但并没有被浏览器发现,这确实也不能怪浏览器太笨。
- 那就每张二维码都给一个唯一的ID? 项目路径下的文件肯定会爆炸,到时候会被项目经理叫去喝茶。
- 那就在想想办法,反复搜索和实践,第二种实现逻辑就出现了:
- 用户 ajax 请求生成二维码内容,返回给页面,前端使用第三方生成二维码类库 qrcode.js 在前端生成二维码。
-
new QRCode(document.getElementById("qrcode"), data.Link);
- 想了解 qrcode.js 的到官网:http://davidshimjs.github.io/qrcodejs/。
- 这种流程的实现方式,完全摒弃了后端生成二维码的部分代码、将生成二维码图片放入项目路径的两个过程。
- 前端随用随生成,需要注意的是返回给前端的跳转链接中的参数需要加密处理,毕竟前端是个是非之地。
- 大公司的前端二维码生成,估计和第二种解决方案差不了多少。