侧边栏壁纸
博主头像
贯耳症博主等级

瓜虫冬匕ing……

  • 累计撰写 67 篇文章
  • 累计创建 49 个标签
  • 累计收到 674 条评论

目 录CONTENT

文章目录

微信浏览器跳转技巧

贯耳症
2019-10-22 / 0 评论 / 1 点赞 / 875 阅读 / 4,047 字

在微信公众号开发中,不可避免地要遇到下载软件、支付宝支付等需求,而这些需求都是无法在微信浏览器内部实现的,那么在微信浏览器内自动跳转到外部浏览器就是一个刚需了。

百度一下微信跳转,可以发现大部分结果都被这些跳转平台承包了。

这张图片不知道为什么被删掉了,那就不添加了。大家可以自行搜索看看。

然后打开一个还可以用的跳转平台,可以看到最主要的功能就是:

  • IOS微信会提示用户右上角打开浏览器(这谁还不会提示呀)
  • 安卓微信则是自动用默认浏览器打开链接(我们主要就是实现安卓端的自动跳转功能)

然后看了一下价格,500块?一个月?最低?溜了溜了溜了。

不过穷人也有穷人的办法,这些平台显然没有和微信合作,那么他们是怎么做到这个跳转功能的呢?我们需要跟踪调研一番。。。

打开这个平台的演示二维码,我的是苹果手机,扫描之后确实只显示了请点击右上角选择Safari打开的提示。

然后我解析了这个二维码,得到一个地址,直接在浏览器打开。哇噻,神奇呀,竟然跳到百度了。

经过以上步骤,已经验证了以下两点:

  1. 苹果手机确实只能用户手动打开浏览器
  2. 普通浏览器可以直接跳转到指定页面

那么现在需要验证的就是安卓微信里面打开这个网页是否可以跳转到外部浏览器并打开指定页面。

不过在此之前,我们先对普通浏览器打开这个网页的所有请求进行抓包,稍后比较与安卓微信打开这个网页的请求进行比较,看看两者是不是有哪些不一样的地方导致了安卓微信可以跳转到外部浏览器而不是直接打开页面。

先看第一个请求,这是我们解析的网址,然后重定向到了http://jumpqq.doupie.cn这个网址,看域名可以发现,这应该是一个新浪微博的短网址生成工具,最后的jumpqq.doupie.cn才是我们真正跳转到的地址。

然后在这个真正的网址中,它又重定向到了www.baidu.com,也就是刚刚我们看到的页面。

分析了普通的浏览器跳转流程之后,我们来验证和分析一下安卓微信浏览器里面的跳转流程。

打开genimotion模拟器并安装微信,然后随便找个聊天框输入刚刚解析出来的网址并打开,可以发现确实是自动弹出了跳转浏览器的选项(我没有设置默认浏览器,如果设置了会直接使用默认浏览器打开)。

现在问题来了,怎么抓包呢?

在Chrome浏览器地址栏输入chrome://inspect/#devices打开设备管理界面,如果此时你的微信浏览器还没有关掉的话,稍等一下应该可以看到一个页面在手机下面的列表中。

Tips:使用这个调试功能需要FQ,如果没有FQ的话是可以显示这个页面但无法打开具体页面的开发者工具的。

下面还有一个问题,只有手机里面已经打开了页面这个列表里面才会显示,我们才能去抓包。而我们要分析的主要就是打开这个页面之前的请求流程,此时我们在自己电脑上编写一个HTML文件并放到Nginx服务器上,页面里面就放一个链接,指向刚刚的那个网址。这样的话就是先打开自己写的页面,然后电脑上打开该页面的调试工具,然后点击刚刚的链接就可以成功抓到我们需要的请求了。

<!DOCTYPE html>
<html lang="zh-cmn-hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<title>微信跳转测试</title>
</head>
<body>
<a href="http://sinaurl.cn/AiYTFMTB">下载</a>
</body>
</html>

在微信中输入并打开我们刚刚写的页面(地址要用电脑的局域网地址),先不要点击下载,等待Chrome浏览器设备调试页面出现这个页面之后,点击标题下方的inspect,等待片刻即可看到熟悉的开发者工具了。

然后把开发者工具切换到Network一栏。

在模拟器中点击下载这个超链接

然后来分析这次请求中究竟有什么是和普通浏览器的请求是不同的:

第一步还是短网址的重定向,和普通浏览器流程相同。

但在真正跳转的网址里面就有不同之处了,首先状态码变成了206,然后Headers里面还多了一个Content-Disposition属性,那么我想应该就是这两处不同导致可以在安卓微信里跳转到外部浏览器了。

百度百科HTTP状态码206含义(部分):

206 Partial Content

服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。

MDN Content-Disposition含义:

在常规的HTTP应答中,Content-Disposition`响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。

作为消息主体中的消息头

在HTTP场景中,第一个参数或者是inline(默认值,表示回复中的消息体会以页面的一部分或者整个页面的形式展示),或者是attachment(意味着消息体应该被下载到本地;大多数浏览器会呈现一个“保存为”的对话框,将filename的值预填为下载后的文件名,假如它存在的话)。

查阅上方资料得知这两个东西都是在告诉微信浏览器,我接下来要做的事你干不了,赶紧找个专业的来干吧。

理解了关键点之后,也就知道要做到跳转这个功能,最重要的是服务端的响应,我这里就以Nginx为例,配置了当请求来自微信浏览器时,就把某个路径下的页面响应加上特殊的请求头:

server {
		listen 80;
		
		location / {
			root html;
			
		}
		
		# 指定目录下的文件
		location /test/ss/ {
			# 微信内置浏览器
			if ($http_user_agent ~* (MicroMessenger)) {
				add_header Content-Type "text/plain; charset=utf-8";
				add_header Content-Disposition "attachment;filename=open.apk";
				return 206;
			}
		}
	}

然后就在test目录下新建一个ss目录,然后放上我们要跳转的页面(即微信会屏蔽的页面),随便写点内容,然后修改我们刚刚的“首页”,把地址换为这个随便写的页面地址。

<!DOCTYPE html>
<html lang="zh-cmn-hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<title>微信跳转测试</title>
</head>
<body>
<a href="http://192.168.3.132/test/ss/toc.html">下载</a>
</body>
</html>

然后尝试在微信里面打开这个链接,就可以实现跳转浏览器的效果了。

至此,主要功能已经实现了,但还有一个短网址生成服务,我们可以用下面这个网站提供的服务,不仅可以手动输入,还提供API生成,可以说十分良心了。

http://www.sina-url.cn/

下面写一下我想的微信跳转功能的完整思路:

根据上面的思路,还有一些做法需要完善:

服务端判断安卓微信

# nginx不支持&&和||和if嵌套,通过变量来解决
set $flag 0;

if ($http_user_agent ~* MicroMessenger){
		set $flag “${flag}1”;
}

if ($http_user_agent ~* Android){
		set $flag “${flag}1”;
}

# 此时,如果有一个为真,flag=01,全部为真,flag=011
if ($flag = "011") {
		add_header Content-Type "text/plain; charset=utf-8";
		add_header Content-Disposition "attachment;filename=open.apk";
		return 206;
}

js判断微信浏览器

function is_weixn(){  
     var ua = navigator.userAgent.toLowerCase();  
     if(ua.match(/MicroMessenger/i)=="micromessenger") {  
         return true;  
     } else {  
         return false;  
     }  
} 

这样一整套流程下来,就实现了区分不同设备,对于可以自动跳转设备进行跳转了。

怎么样?我不是一个标题党吧,嘿嘿

1

评论区