完美解决微信扫码后自动下载APK被拦截难题
因为微信的拦截机制限制,若二维码的URL 后缀为.apk扫码后微信会自动进行拦截,并进行预警提示。遇到这种情况很多用户就不会继续下载了,这样导致大量潜在客户的流失。
经过一阵子的研究并结合网上给出的方案,最终解决了该难题,废话不多说直接上硬菜:
以安卓为例
请注意:
只写关键代码供同行参考交流,小白建议直接略过或发站内信探讨
有两种方案解决,第一种效果是扫码后显示引导页提醒用户点击右上角菜单选择系统浏览器打开(这种市面上常见)如下图:
图一
另一种效果是扫码后微信直接提醒使用系统内置浏览器打开,如下图:
图二
以JAVA语言为例
方案一:扫码后显示提示页
一:例如你的域名是www.csdn.net, 二维码的内容为:https://www.csdn.net/tip 写一个Controller来处理请求:
@RequestMapping("/tip")
public String handleRequest(){
return "tip"; // 引导页html
}
引导页关键JS代码:
function isVchat() {
// 获取浏览器UA信息
var ua = navigator.userAgent.toLowerCase();
// 判断是否为微信浏览器
return ua.match(/MicroMessenger/i) == "micromessenger";
}
// 此处使用了jQuery, 若不想使用jquery,直接写JS原生代码即可
$(window).on("load",function(){
// 判断是否为微信浏览器
var isWeixin = isVchat();
// 如果是微信浏览器则显示图一提示图片
if(isWeixin){
// 把隐藏的div 显示出来
$(".weixin-tip").show();
}else{
// 注意:此处不能直接写 https://www.csdn.net/app.apk,这样写系统浏览器也会给出警告提示,可以将浏览器URL重定向至下载路径
window.location.href = "/down";
}
});
后端写个Controller处理,
/**
* 下载APK
* */
@RequestMapping("/down")
public void toDown(HttpServletResponse response){
// 你的APK下载路径
String apkFilePath = "/release.apk";
// 通知浏览器访问该路径(重定向)
response.setHeader("Location", apkFilePath);
// 设置状态码为302 暂时移动
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
}
通过以上操作即可解决微信扫码后APK下载被拦截的问题。
方案二:微信扫码后唤醒手机自带浏览器下载APK
思考过程:
1.扫码后微信会访问具体的URL,通过后端的返回结果来检测是否会有恶意行为,若存在恶意行为则拦截,若不存在则放行。首先确认的一点就是后端的响应必须符合微信浏览器的安全规范。
2.如何才能让微信主动提示用户应使用自带浏览器来访问,这个就是比较头疼的问题了,但是办法总比问题多,只要肯研究就没有啃不下的硬骨头。经过研究发现,微信遇到自身浏览器处理不了的文件类型,且该文件类型也是常规文件无风险的时候就会提醒用户使用自带浏览器打开该文件。掌握这个逻辑后就可以开始编码了,域名仍然以www.csdn.net为例,若使用自己的域名该被网友骂发外链了。
一:生成一个二维码,链接为:https://www.csdn.net/tip
二:tip.html JS关键代码
function is_weixin() {
var ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
return true;
} else {
return false;
}
}
$(window).on("load",function(){
var winHeight = $(window).height();
var isWeixin = is_weixin();
if(isWeixin){
// 此处仍然正常显示提示图片内容,访问未知原因没有弹出提示使用系统浏览器访问,补救措施
$(".weixin-tip").show();
// 注意此处,若为微信浏览器,则尝试请求/123.pdf
window.open('/123.pdf', '_blank');
}else{
// 若不是微信浏览器扫码 则直接给出下载地址
window.location.href = "/down";
}
});
二:后端Controller处理请求
/**
* 直接下载APK的方法
* */
@RequestMapping("/down")
public void toDown(HttpServletResponse response){
String apkFilePath = "/release.apk";
response.setHeader("Location", apkFilePath);
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
}
/**
* 请求123.paf的方法逻辑
* 微信浏览器请求访问123.pdf风险检测通过以后就会给出提示建议使用系统浏览器来访问123.pdf
* 当系统浏览器访问/123.pdf时间通过判断UA信息,若不是微信浏览器则直接重定向到APK的下载界面
* */
@GetMapping("/123.pdf")
public void redirectPdfToPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 判断是否为微信浏览器
boolean isWeChat = request.getHeader("User-Agent").toLowerCase().contains("micromessenger");
// 如果是微信浏览器则输出123.pdf文件
// 注意:如果不输出的话它也会拦截或者报错,所以必须要像处理正常文件一样输出
if(isWeChat){
// 设置文件类型
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=123.pdf");
File file = new File("./123.pdf");
try (InputStream is = new FileInputStream(file); OutputStream os = response.getOutputStream()) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.flush();
}catch (Exception e){
log.error("pdf文件不存在");
}
}else{
// 如果不是微信浏览器则可以重定向下载APK文件了
String apkFilePath = "/release.apk";
response.setHeader("Location", apkFilePath);
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
}
}
以上两种方案都可以解决微信扫码下载APK被拦截的问题。若需要帮助请发站内信