0. 背景

最近遇到一个需求是H5通过微信公众号打开一个pdf链接(url形式,浏览器输入url可直接下载)看上去很简单,不过还是有不少要注意的。

1. 如何打开文件

拿到需求第一想法,怎么打开链接呢?window.open? window.location.href? 方法还是挺多的。MDN回顾.

window.open:指定名字将相关资源加载在浏览器新窗口上。

//  pdfUrl:要加载的资源,strWindowName,可选,窗口名称。
let windowObjectReference = window.open(pdfUrl, strWindowName);

我这里只需要填写pdfUrl即可,当然跟打开新网页的效果不同。在pc端实现的效果是直接下载pdf。

但是,但是,第一次做移动端,才涨知识了,苹果端可以直接显示弹窗并下载,安卓端就会出现如下信息:
网上的说法挺多的,也有说在安卓微信公众号可以使用window.open,有说不行的。但我查到的是说以前微信公众号很多不良商家通过window.open打开非法页面,用户体验不好,所以如果通过window.open开启组织弹出窗口的政策(见上图)。然后试了window.location.href

window.location: 只读对象,返回location对象,包含有关文档当前位置的信息

// 两者等价
window.location.href = 'www.baidu.com';
window.location = 'www.baidu.com';

不过这里也有坑(我后来发现可能是pdfUrl的原因还好,还是要注意!),如安卓用window.location.href从微信浏览器跳转原生浏览器无效,查阅网络发现可能是缓存的问题,加上时间戳来刷新缓存。

window.location.href = url + '?time='+((new Date()).getTime());

和领导沟通后,安卓机这块需求变成:微信公众号内,点击“下载”后显示弹窗,引导用户从默认浏览器打开再下载pdf。这里就需要判断用户所处于什么浏览器了(微信内置浏览器/手机原生浏览器)。

2. 适配不同端

判断用户浏览器处于什么环境,JS提供了一个很强大的API: navigator.userAgent

navigator.userAgent: 返回用户现在浏览器的用户代理

以我自己windows端Chrome浏览器为例子

console.log(navigator.userAgent);
// Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36

这样就好说了,通过indexOf,match都可以判断浏览器环境,

// 判断是否移动端
// /i不区分大小写模式
const isMobile = /Mobi|Android|iPhone/i.test(u);
//判断是否是安卓
const isAndroid = navigator.userAgent.indexOf('Android') > -1 || navigator.userAgent.indexOf('Linux') > -1;
//判断是否是ios
const isIOS = !!navigator.userAgent.match(/\(i[^;]+;(U;)? CPU.+Mac OS X/));
// 判断是否是微信
const isWeixin = navigator.userAgent.toLowerCase().indexOf('micromessenger') !== -1;

判断浏览器所处环境可参考此网站:根据UserAgent判断浏览器类型

不过,这个地方有个问题需要注意(MDN上提出:Navigator.userAgent)
这种方式要浏览器提供了尽可能少的信息。不要假设此浏览器这个属性的值在未来版本有相同的值。
如我的安卓手机默认浏览器用这个方法就是ios端(??),不过大部分都可以通过判断进行下载就好,不然测试成本太高了。

所以,领导给我的需求(见标题2)就变成了:
(1)判断是否是移动端,是进(2),不是直接window.location.href下载pdf(后来跟老师聊其实这步可以不要,毕竟是移动端的组,但以防万一还是判断下
(2)判断是安卓还是苹果,是进(3),不是直接window.location.href下载pdf
(3)判断是在微信内置浏览器还是手机原生浏览器,是微信先显示弹窗,告诉用户点右上角…通过浏览器重新进入该页面下载,如果不是微信浏览器,不显示弹窗直接下载

3. iOS端下载文件名null

在产品测试的时候,发现iOS点击下载后会出现一个情况,window.open(url)有这个问题。

查阅资料看到一个微信公众号官方人员的回答,应该是相关的:

这里弹窗时还没有真正开始下载,显示的文件名依赖请求response header中Content-Disposition的filename,你没有填这个字段,所以拿到的是空的。后面真正开始下载客户端才能拿到文件名
来源: 微信内置浏览器下载pdf标题null

但领导意思是,虽然后端Content-Disposition没有填写,但尽量不让数据提供方改接口内容(毕竟要磕头)。最后他给了一种解决方法。

// 创建XHR对象
const x = new window.XMLHttpRequest();
// 发送XHR请求
x.open('GET', url, true);
// 返回文件类型
x.responseType = 'blob';
x.onload = () => {const url = window.URL.createObjectURL(x.response);const a = document.createElement('a');a.href = url;a.download = '123345.pdf';a.click();
};
x.send();

一点点啃:

XMLHttpRequest(XHR):此对象与服务器交互,在XMLHttpRequest可在不刷新页面时请求特定URL,获取数据。AJAX编程中使用
open(): 规定请求方法,请求url,是否异步请求
send(): 请求发到服务器

这样重新发送了请求在ios进行pdf下载进行文件下载时文件名null的问题。

4. 其他

  1. vconsole查看接口情况,存储信息。当确定要传生产环境了记得注释掉
import VConsole from 'vconsole';
const vConsole = new VConsole();
  1. 不同页面数据传值的方法:
  • vuex(复杂)
  • localStorage(不同页面存储内容不相互独立)
  • sessionStorage(关页面就没了)
  • cookie(不安全,存储数据少)
  • 路由传参
    当微信内置浏览器打开原生浏览器时是两个浏览器啊,localStorage肯定不同,传参方式用路由传参!

小许继续努力!

H5 微信公众号打开pdf文件的思考相关推荐

  1. 微信公众号打开的h5网页点击按钮返回公众号

    从微信公众号打开的h5网页 退出h5返回到公众号方法 closePage() {if (typeof WeixinJSBridge == "undefined") {if (doc ...

  2. H5微信公众号,如何在页面点击按钮打开分享面板【求助】

    1.使用了weixin-js-sdk,只实现了自定义右上角的分享功能 安装命令: npm install weixin-js-sdk --save import wx from 'weixin-js- ...

  3. vue h5微信公众号授权获取用户信息

    vue h5微信公众号授权获取用户信息 1.申请测试账号 https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 2.修改网页授权 ...

  4. 微信公众号打开微信内置地图(thinkphp5+jq)

    h5或微信公众号打开微信内置地图,选择高德,百度等导航 第一步,去后台请求签名数据 this.$http.get(后端地址:获取下面所需要的的数据).then(data => {// 记录tok ...

  5. vue 公众号扫描_vue编写微信公众号打开相机功能

    vue编写微信公众号打开相机功能,什么都不多说直接上代码 页面布局代码 class="previewer-demo-img" :key="index" :src ...

  6. 微信公众号添加word文件

    微信公众号添加word文件的教程 我们都知道创建一个微信公众号,在公众号中发布一些文章是非常简单的,但公众号添加附件下载的功能却被限制,如今可以使用小程序"微附件"进行在公众号中添 ...

  7. 记录一次用vant框架做h5微信公众号

    这次是用vant框架做一个h5微信公众号,是在我一同事封装的基础上开发的.封装的项目在gitee上的地址:湖南巨仑网络科技有限公司/vant-H5移动端封装 - Gitee.com.内容有底部导航的, ...

  8. 使用beecloud和easychat 做微信H5 微信公众号支付遇到的坑

    首先我先来说明微信h5和微信公众号支付的区别 微信H5指的是微信网页端支付.微信公众号支付指的是微信浏览器内发起微信支付,这种支付都是属于微信公众号支付.俩者本质的区别就是H5不需要微信网页授权,但是 ...

  9. 教你如何下载微信公众号的音频文件

    无意中在微信公众号里面听到了自己喜欢的原创音乐或者诗歌朗诵,想保存下来,但是微信却没有提供音频下载功能,这可怎么办,别着急,我来帮帮你. 工具/原料 ·         我以360和QQ浏览器为例,其 ...

最新文章

  1. HTTP协议解析之Cookie
  2. 亿级Web系统搭建——单机到分布式集群
  3. cmake教程(为什么要用cmake?)(cmake编译opencv)(就是个跨平台的编译工具Linux、windows)(很重要,必须得学)(报错解决方案)opencv编译
  4. C/C++头文件大全
  5. SQLserver删除某数据库中所有表 方法 二
  6. Spring MVC:测试简介
  7. docker修改镜像的存储位置_云原生存储详解:容器存储与 K8s 存储卷(内含赠书福利)...
  8. b超可以看出什么_B超可以查出什么
  9. 勤于思考:Asp.Net MVC Html.TextBoxFor日期格式化
  10. MAT插件分析内存泄露之二
  11. Activiti-modeler使用
  12. Android酷炫有用的开源框架
  13. 通信原理第七版樊昌信 课后习题答案详解
  14. 微信内置浏览器cookie设置问题
  15. 机器学习基础-特征工程简析
  16. 首次适应算法 C语言实现
  17. python实现千牛客服自动回复语_千牛快捷回复短语大全,千牛自动回复语大全
  18. Android仿微信上传图片发朋友圈
  19. JVM面试专题(上)
  20. 基于51单片机的交通灯控制系统课程设计(含proteus仿真图及代码)

热门文章

  1. 鸿蒙是怎样的境态,《镇魔曲》鸿蒙境副本怎么样 鸿蒙境副本介绍
  2. 一本通c语言在线测评答案,51单片机典型项目实战全能一本通(C语言版)(视频版)最新章节_张毅刚著_掌阅小说网...
  3. 深入理解PBFT算法的提交阶段
  4. 电力监控系统在多协议粮食港区中的设计与应用
  5. 计算机专业内存8g和16g差距大吗,电脑内存8g和16g的区别大吗?
  6. ubuntu下显卡(独显,集显)切换
  7. Jeesite 4.3 按钮权限,设置按钮只针对某个账号显示及使用
  8. APICloud-App-Templates
  9. 86 - 得到整数列表的中位数
  10. 齿轮过载、偏心、不对中、断齿特征分析及信号特征提取