起二維碼,似乎一直以來都是手機(jī)的專利。不過,有些時候,我們可能希望在電腦上也能掃描二維碼:
當(dāng)二維碼是個網(wǎng)址時,手機(jī)網(wǎng)速不行,掃半天還沒打開網(wǎng)頁
手機(jī)內(nèi)有網(wǎng)銀,擔(dān)心不安全,電腦反正是男朋友用的,他百毒不侵
手機(jī)不在身邊,朋友只發(fā)過來了一個二維碼
……
那么,在電腦上到底能不能掃描二維碼?如果能,又該怎么做呢?在這里,向大家介紹一個供電腦使用的二維碼插件:Anything to QRcode 1.1.2(下面簡稱插件)。當(dāng)我們在瀏覽器上安裝了該插件時,就可以在瀏覽網(wǎng)頁時掃描二維碼了。
【在瀏覽器上安裝插件】
首先,將插件下載到本地電腦上,然后打開瀏覽器,并將瀏覽器窗口略微縮小一些。再用鼠標(biāo)左鍵將插件拖到瀏覽器窗口中來。
圖示 將插件拖入瀏覽器窗口
等到插件拖到瀏覽器窗口中以后,再松開鼠標(biāo)按鈕。此時會彈出一個詢問對話框,請點(diǎn)擊相應(yīng)按鈕允許添加插件。就這樣,插件就安裝好了。
【怎樣使用插件進(jìn)行二維碼掃描】
之后,當(dāng)我們?yōu)g覽網(wǎng)頁時,如果碰到想掃描的二維碼,則可以在二維碼圖片上右擊鼠標(biāo),選擇“Anything to QRcode”-“解析二維碼”。
這時,將會顯示出該二維碼所包含的實(shí)際信息(比如說,一個網(wǎng)址)。接下來,我們就可以根據(jù)獲取的信息做我們想做的事情了。
【注意】
如果該二維碼包含的信息不是網(wǎng)址,而是一個手機(jī) App,則無法在電腦上使用該插件解析成功。
信每次更新都是一句「解決了一些已知問題」,導(dǎo)致很多用戶每次升級都不知道具體有哪些新變化。就比如最新更新的微信 for Windows,大家都知道是這是一次集中于「存儲空間管理」的升級,帶來了聊天數(shù)據(jù)、聊天記錄備份文件、緩存這三大類文件的清理操作,可以讓用戶快速查看自己的微信已用存儲空間。而很多用戶不知道的是,最新版微信 for Windows 還帶來一個大家期待許久的功能-掃描圖片二維碼。
在電腦上總會遇到一些需要掃描二維碼的地方,比如好友發(fā)過來的帶二維碼的圖片,之前我們都必須先拿出手機(jī)完成掃碼才能進(jìn)行下一步操作,過程稍顯麻煩。因此也經(jīng)常有用戶向微信團(tuán)隊提出建議,希望可以在電腦端微信上加入識別二維碼的功能。好消息是,現(xiàn)在這個問題終于得到解決了,微信在最新發(fā)布的 for Windows 版本中,加入了大家期待許久的「掃描圖片二維碼」功能,以后不用再拿出手機(jī)了。
操作方式有兩種,都很簡單。第一種是通過微信截圖的方式,如果截圖區(qū)域內(nèi)包含二維碼,在截圖的時候就能在下方工具欄中看到本次新增的「二維碼」圖標(biāo),點(diǎn)擊即可進(jìn)行掃碼操作。第二種是通過點(diǎn)擊圖片查看大圖的方式,同樣如果所選擇圖片中包含二維碼,在查看大圖的時候上方功能欄就會新增一個「二維碼圖標(biāo)」,點(diǎn)擊即可識別。
另外值得一提的是,微信 for Mac 也加入了這項功能,操作方式與 Windows 端一致。
最后簡單總結(jié)一下,這次的微信 for Windows 更新算是采納了用戶的建議,同時基于整體更新內(nèi)容來看,這應(yīng)該也能算是今年以來在 Windows 端的最大一次升級。另外,針對電腦端微信,希望微信團(tuán)隊可以解鎖一下大文件發(fā)送,以及解決圖片和視頻的壓縮問題,這對于以微信作為主要辦公軟件的同學(xué)來說真的很重要。
那么,你還希望微信可以加入什么功能呢?我先來,漂流瓶。
在很多PC端的網(wǎng)站為了用戶登錄方便都提供了掃描二維碼實(shí)現(xiàn)用戶登錄的功能,通過移動端掃描PC端的二維碼并且在移動端進(jìn)行用戶確認(rèn)登錄之后實(shí)現(xiàn)PC端網(wǎng)頁的登錄操作。而對于掃碼登錄來講其實(shí)現(xiàn)方式也比較簡單,下面我們就來基于SpringBoot實(shí)現(xiàn)一個掃描登錄功能。
在SpringBoot項目中我們可以利用第三方庫來自己生成二維碼,或者是我們可以調(diào)用一些第三方的系統(tǒng),例如微信、QQ、或者是其他平臺來生成二維碼的連接。下面我們演示如何使用Zxing來生成一個二維碼。代碼如下。
public class QRCodeLoginController {
private String generateQRCode(String loginToken) {
String qrCodeBase64=null;
try {
// 設(shè)置二維碼參數(shù)
int width=300;
int height=300;
String charset="UTF-8";
String qrCodeData="loginToken=" + loginToken;
// 使用zxing庫生成二維碼圖片
QRCodeWriter qrCodeWriter=new QRCodeWriter();
BitMatrix bitMatrix=qrCodeWriter.encode(qrCodeData, BarcodeFormat.QR_CODE, width, height);
// 將BitMatrix轉(zhuǎn)換為BufferedImage
BufferedImage bufferedImage=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
bufferedImage.createGraphics();
Graphics2D graphics=(Graphics2D) bufferedImage.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, width, height);
graphics.setColor(Color.BLACK);
for (int i=0; i < width; i++) {
for (int j=0; j < height; j++) {
if (bitMatrix.get(i, j)) {
graphics.fillRect(i, j, 1, 1);
}
}
}
// 將BufferedImage轉(zhuǎn)換為Base64編碼
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", baos);
byte[] bytes=baos.toByteArray();
qrCodeBase64=Base64.getEncoder().encodeToString(bytes);
} catch (WriterException | IOException e) {
e.printStackTrace();
}
return qrCodeBase64;
}
}
生成二維碼之后,可以將二維碼連接顯示到登錄頁面上。這里需要注意,生成的二維碼中一定要包含一個隨機(jī)生成的唯一的用來完成登錄操作的唯一標(biāo)識,通過這個唯一標(biāo)識來驗(yàn)證用戶的登錄操作。如下所示。
@GetMapping("/login")
public String getQRCode() {
// 生成隨機(jī)登錄標(biāo)識符
loginToken=UUID.randomUUID().toString();
// 生成二維碼圖片
String qrCodeUrl=generateQRCode(loginToken);
return qrCodeUrl;
}
在很多時候開發(fā)者對于生成二維碼,進(jìn)行用戶唯一ID校驗(yàn)都沒有什么疑惑,唯獨(dú)就對前端如何進(jìn)行調(diào)用而產(chǎn)生了疑惑,到底是通過輪詢的方式還是通過WebSocket的方式來進(jìn)行接口驗(yàn)證調(diào)用來判斷到底用戶是否在移動端點(diǎn)擊了授權(quán)。
這里我們提供了輪詢的實(shí)現(xiàn)方式。在很多的網(wǎng)站實(shí)現(xiàn)掃碼登錄的時候都采用了這種方式,通過定時輪詢檢查用戶是否在移動端點(diǎn)擊了授權(quán)登錄。
<script>
// 定時輪詢檢查登錄狀態(tài)
setInterval(function() {
$.get("/checkLogin", function(data) {
if (data==="Login success") {
// 登錄成功,更新頁面顯示
$("#loginStatus").text("Login successful!");
}
});
}, 3000); // 每隔3秒鐘檢查一次登錄狀態(tài)
</script>
如果用戶點(diǎn)擊了授權(quán)登錄的操作,那么當(dāng)服務(wù)端用戶狀態(tài)發(fā)生了變化之后,PC端通過接口檢查用戶狀態(tài)是否授權(quán),來判斷用戶是否可以進(jìn)入系統(tǒng),授權(quán)成功。如下所示。
@GetMapping("/checkLogin")
public ResponseEntity<String> checkLoginStatus() {
if (userLoggedIn(loginToken)) {
// 用戶已經(jīng)掃碼登錄
return ResponseEntity.ok("Login success");
} else {
// 用戶未掃碼登錄
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Login not completed");
}
}
private boolean userLoggedIn(String loginToken) {
// 檢查用戶是否已經(jīng)掃碼登錄,根據(jù)登錄標(biāo)識符查詢登錄狀態(tài)
// 返回 true 表示用戶已經(jīng)登錄,否則返回 false
// 此處僅作示例,實(shí)際情況需要根據(jù)業(yè)務(wù)邏輯實(shí)現(xiàn)
return false;
}
對于移動端用戶是否認(rèn)證的功能判斷需要根據(jù)用戶具體的業(yè)務(wù)邏輯來實(shí)現(xiàn),這里不做展示。
如果在用戶掃描過程中、或者是用戶掃碼完成之后點(diǎn)擊了取消,那么這個時候PC端并不知道用戶的這種操作,輪詢調(diào)用檢查還在繼續(xù),在這種情況下,如果對操作沒有進(jìn)行處理的話,就會導(dǎo)致網(wǎng)絡(luò)資源的消耗。因?yàn)镻C端一直在輪詢檢查用戶狀態(tài)。所以要對超時情況,異常情況等各種情況進(jìn)行驗(yàn)證。
上面我們介紹了關(guān)于如何實(shí)現(xiàn)PC端掃碼登錄的功能,整體流程分為了四個步驟。第一步、二維碼的生成(包括隨機(jī)登錄標(biāo)識等情況);第二步、前端登錄檢查實(shí)現(xiàn);第三步、移動端調(diào)用服務(wù)器進(jìn)行用戶狀態(tài)調(diào)整;第四步:超時或者是異常處理。當(dāng)然這些操作在單機(jī)狀態(tài)下實(shí)現(xiàn)起來都沒有問題,但是在分布式、高并發(fā)情況下需要考慮的內(nèi)容就比較多了。希望讀者可以有所區(qū)別。