原理
-
点击扫码登录时,向服务器发送请求,生成qrid和image地址。并开启轮询
-
向服务持续请求,大概2s一次,返回二维码状态
- 未使用。
- 二维码已扫描,请客户端确定。
- 二维码已失效。 会调用第一步重新生成二维码图片
如果二维码图片关闭,轮询也会关闭。减少服务器请求
实现
大概也只有三步,因为ajax禁止了跨域请求,只能在java后端实现。
- 获取图片地址,并返回前端,用于页面展示。
@GetMapping("/getimg")
@ResponseBody
public String getimg() throws IOException {
String url = "https://login.sina.com.cn/sso/qrcode/image?entry=weibo&size=180&callback=STK_" + System.currentTimeMillis();
String body = Jsoup.connect(url).ignoreContentType(true).execute().body();
JSONObject jsonObject = JSONObject.parseObject(StringUtils.substringBetween(body, "(", ")"));
imageurl = jsonObject.getJSONObject("data").getString("image");
qrid = jsonObject.getJSONObject("data").getString("qrid");
String data = "https://v2." + imageurl.substring(2, imageurl.length());
System.out.println(data);
return data;
}
- 校验二维码状态。
@GetMapping("/check")
@ResponseBody
public String check(HttpSession session) throws IOException, InterruptedException {
String url = "https://login.sina.com.cn/sso/qrcode/check?entry=weibo&qrid=" + qrid + "&callback=STK_" + System.currentTimeMillis();
String body = Jsoup.connect(url).ignoreContentType(true).execute().body();
System.out.println(body);
JSONObject jsonObject = JSONObject.parseObject(StringUtils.substringBetween(body, "(", ")"));
if ("20000000".equals(jsonObject.getString("retcode"))) {
//执行登录操作
}
return jsonObject.getString("retcode");
}
- 前端ajax调用。
$("#login").click(function () {
$.get("/getimg", function (data) {
$("#login_image").attr("src", data);
});
$(".ui.page.dimmer").dimmer('show');
var timer1 = setInterval(checkScan, 2500);//每隔3s执行一次checkScan
function checkScan() {
$(".ui.page.dimmer").dimmer({
onHide: function () {
clearInterval(timer1);
}
});
$.get("/check", function (data) {
if (data == "50114001") {
}
if (data == "50114002") {
$('#login_msg').html("已经扫描,请在客户端确认");//将二维码取消,防止其他人再扫
}
if (data == "50114015") {
$.get("/getimg", function (data) {
$("#login_image").attr("src", data);
});
}
if (data == "50114003") {
$.get("/getimg", function (data) {
$("#login_image").attr("src", data);
});
}
if (data == "20000000") {
clearInterval(timer1);
window.location.href = "/";
}
});
}
});