pdfjs解决ie浏览器预览pdf问题

pdfjs是一个js库,可以将pdf文件用canvas重新绘制,从而无需借助pdf读取插件就可以直接预览。
目前chrome内核的浏览器已内置pdf读取插件,但ie浏览器还没有。而我们最近在做的一个项目使用对象是医院,使用的浏览器竟然还是ie。所以我们只能把项目用js重写(当然也可以用jQuery的)。
首先模拟ie浏览器就是个挑战。长期做B端项目被惯坏了,早就忘记还有ie这么个天使了。官网已经不提供ie的下载渠道,搜索了一圈,发现用edge模拟是一个比较好的选择。
在windows11中打开ie浏览器的步骤是:

  1. 首先,按 Win + R 打开运行窗口
  2. 接下来,在运行命令框中输入 inetcpl.cpl
  3. 单击 确定 进入 Internet 属性窗口
  4. 选择 程序 选项卡,点击 管理加载项 按钮
  5. 然后,点击窗口底部 了解有关工具栏和扩展的详细信息
    这样就打开了可爱的ie浏览器。

原生js获取xhr的主体方法

function Request(){this.httpRequest = function(obj,successfun, errFun){var xmlHttp = null;//创建 XMLHttpRequest 对象,老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")if(window.XMLHttpRequest){//code for all new browsers()xmlHttp = new XMLHttpRequest;}else if(window.ActiveXObject){//code for IE5 and IE6xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");}//判断是否支持请求if(xmlHttp == null){alert("浏览器不支持xmlHttp");return;}//请求方式, 转换为大写var httpMethod = (obj.method || "Get").toUpperCase();//数据类型var httpDataType = obj.dataType || 'json';//urlvar httpUrl = obj.url;//异步请求var async = true;//post请求时参数处理if(httpMethod == "POST"){//请求体中的参数 post请求参数格式为:param1=test&param2=test2var data = obj.data || {};var requestData = '';for(var key in data){requestData = requestData + key + "=" + data[key] + "&";}if(requestData == ''){requestData = '';}else{requestData = requestData.substring(0, requestData.length - 1);}}//请求接口if(httpMethod == 'GET'){xmlHttp.open("GET", httpUrl, async);xmlHttp.send(null);}else if(httpMethod == "POST"){xmlHttp.open("POST", httpUrl, async);xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xmlHttp.send(requestData);}//onreadystatechange 是一个事件句柄。它的值 (state_Change) 是一个函数的名称,当 XMLHttpRequest 对象的状态发生改变时,会触发此函数。状态从 0 (uninitialized) 到 4 (complete) 进行变化。仅在状态为 4 时,我们才执行代码xmlHttp.onreadystatechange = function(){//completeif(xmlHttp.readyState == 4){// 此处用了promise替代了请求成功后的回调if(xmlHttp.status == 200){var res = JSON.parse(xmlHttp.responseText);// var res = xmlHttp.responseText;if (res && res.code == '200') {//请求成功执行的回调函数typeof successfun === 'function' &&successfun(res);} else {//请求失败的回调函数typeof errFun === 'function' &&errFun(res);}} else {var msg = new Error('出错了')//请求失败的回调函数typeof errFun === 'function' &&errFun(msg);}}}}
}var $request = new Request()

数据请求的问题完成了。但是现在pdf文件没有出现在期待的位置,只是在底部出现了一个下载文件的请求提示。查了下,原来是ie没有内置pdf阅读器,所以无法预览,浏览器将pdf文件识别为需要下载。

那么问题来了,解决方法有两个:

1.下载Adobe pdf-reader。
下载地址:https://www.adobe.com/cn/acrobat/pdf-reader.html,还需要再ie浏览器中启用,在管理加载项中修改(管理加载项打开方法见上面那个步骤)
在这里插入图片描述
但这个方法也有一个问题,下载插件对用户是有门槛的,用户很可能不愿意这么麻烦。

2.用pdfjs处理pdf文件。
这样用户不需要额外做任何操作。但pdfjs兼容性有限,只能兼容到ie9,更低版本的浏览器就不行了。
综合评估后还是决定用pdfjs处理。如果还有更低版本的就继续下载pdf阅读器。
高版本的pdfjs已放弃对ie的兼容,需要下载旧版本。在官网选择tags,按照对应指示打包。注意打包旧版本时需要保证node在10以下(我本地的node是16.16.0,怪不得昨天一直报错到崩溃)。
当然也可以找别人已经打好的包,参考地址。
要注意把viewer.js中的defaultUrl清空(这个变量的名称可能不同版本不一样,我当时的变量名是DEFAULT_URL,DEFAULT_URL = ‘compressed.tracemonkey-pldi-09.pdf’)。不清空会报错,报“Missing PDF file”。

再把下载下来的文件地址改写为‘./pdfjs/web/viewer.html?file=’+realUrl。

这样先在chrome发现是正常展示的,没有问题,说明方法写地是对的。但是用ie浏览器打开就是一片黑。昨天崩溃了一天,换了很多个pdfjs版本,今天终于意识到应该看看报了什么错。发现控制台报的错是“附加页针对的是文档模式7,部分控制台api和功能可能无法使用”。针对这个报错,一查发现是因为浏览器设置的默认文档模式是7,导致虽然我的浏览器是ie11,但实际是按照ie7来解析网页,而我的网页是不兼容ie7地,这可不就会报错嘛。
查看了相关文章,发现了应该在头文件加上两句声明。

// 如果安装了 Google Chrome Frame (谷歌浏览器 內嵌框架), 则使用 谷歌浏览器 内核模式,否则使用 最新的 IE 模式(浏览器是哪个版本就用哪个ie模式)
<meta http-equiv="X-UA-Compatible" content="IE=edge chrome=1">
// 双核浏览器兼容,使用 Chromium 内核(极速模式)
<meta name="renderer" content="webkit"/>

自己的html文件和pdfjs的viewer.html都要加上。
还发现了一个宝贝,meta标签声明,可以强制在浏览器中用低版本模式打开网页。

<meta http-equiv="X-UA-Compatible" content="IE=7" /> 

分别变更content中的数字,可以在ie11中分别模拟对应ie版本中的兼容情况。啊啊啊,妈妈再也不用担心我怎样切换ie版本了。
IE模式参考文章。

好了,至此,pdf预览兼容的IE的工作总算完成了。芜湖,为自己鼓掌。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/131326.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基础秘钥、公钥、地址的熟悉指南

1. 地址 0基础漫画式阅读&#xff1a;https://www.cnblogs.com/charlesblc/p/6130433.html 清晰详细的地址生成解释&#xff1a;比特币&#xff1a;账户私钥、公钥、地址的生成 - kumata - 博客园 (cnblogs.com) 对原理更详细解释&#xff1a;区块链技术核心篇之二&#xff…

在微信小程序上怎么实现多门店管理功能

微信小程序已经成为连接线上与线下的重要工具&#xff0c;尤其对于拥有多家门店的企业来说&#xff0c;通过微信小程序可以实现多门店管理&#xff0c;提高管理效率和用户体验。下面&#xff0c;我将为大家详细介绍如何在微信小程序上实现多门店管理功能。 一、确定多门店管理功…

【网络教程】记一次使用Docker手动搭建BT宝塔面板的全过程(包含问题解决如:宝塔面板无法开启防火墙,ssh,nginx等)

文章目录 准备安装安装宝塔面板开启ssh和修改ssh的密码导出镜像问题解决宝塔面板无法开启防火墙无法启动ssh设置密码nginx安装失败设置开机启动相关服务准备 演示的系统环境:Ubuntu 22.04.3 LTS更新安装/升级docker到最新版本升级docker相关命令如下# 更新软件包列表并自动升级…

没有软件怎么管理固定资产

在当今数字化的世界中&#xff0c;我们已经习惯了使用各种软件来管理我们的日常生活和工作。然而&#xff0c;当我们面临一个看似简单的问题——如何管理固定资产时&#xff0c;我们可能会感到困惑。那么&#xff0c;如果没有软件&#xff0c;我们该如何进行资产管理呢&#xf…

文章生成器免费版

你是否曾经陷入文案创作的困扰中&#xff1f;是不是为了撰写出优质的文章而煞费苦心&#xff1f;那么&#xff0c;如果我告诉你&#xff0c;现在有一种神奇的工具&#xff0c;可以为你解决这个问题&#xff0c;让你轻松地生成文章&#xff0c;你会不会感到兴奋呢&#xff1f;让…

Unity实现用WASD控制一个物体前后左右移动-小白课程01

1 根据业务逻辑搭建场景 02 根据业务写代码 using System.Collections; using System.Collections.Generic; using UnityEngine;//实现让被挂在的物体往前移动 //按下W键往前移动&#xff0c;按下S键往后移动 public class RoleMove : MonoBehaviour { public float myspe…

数据在内存中的存储——练习1

题目&#xff1a; int main() {int a[4] { 1,2,3,4 };int* ptrl (int*)(&a 1);int* ptr2 (int*)((int)a 1);printf("%x,%x"&#xff0c;ptr1[-1], *ptr2);return 0; } 思路分析&#xff1a; int* ptrl (int*)(&a 1); ptr1[-1] &a表示的是整个数…

winscope怎么实现user版本上导出方案设计探讨-千里马android framework车载车机手机系统开发

背景 在马哥给讲解怎么用winscope来分析各种闪黑&#xff0c;黑屏等问题后&#xff0c;很多买课的同学都开始使用这个工具用于实际公司的项目了&#xff0c;但是很多同学又开始发现有一个问题&#xff0c;那就发现在user版本的手机设备上发现无法抓取相关的winscope&#xff0…

Qt MinGW / MSVC

MinGW/MSVC的关系 MinGW / MSVC.dll / .lib / .a 的关系 MinGW / MSVC Qt 中有两种方式编译&#xff1a;一种是MinGW &#xff0c;另一种MSVC&#xff0c;是两种不同的编译器。 MinGW(Minimalist GNUfor Windows)&#xff0c;它是一个可自由使用和自由发布的Windows特定头文件…

PMP-项目启动过程组的重要性

一、什么是项目启动过程组 启动过程组包括定义一个新项目或现有项目的一个新阶段&#xff0c;授权开始该项目或阶段的一组过程。启动过程组的目的是&#xff1a;协调相关方期望与项目目的&#xff0c;告知相关方项目范围和目标&#xff0c;并商讨他们对项目及相关阶段的参与将如…

springboot导出(POI)

POI官方文档 引入依赖 <!--POI--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId&…

Redis——其他数据类型介绍

概要介绍 Redis中有10种不同的数据类型。之前的blog中介绍了Redis中常见的五大数据类型&#xff1a;String&#xff0c;List&#xff0c;Hash&#xff0c;Set&#xff0c;ZSet。而Redis中还有许多其他的数据类型&#xff0c;一般在特定的场景中使用 Stream 首先介绍一下什么…

MySQL日常使用记录

1.时间 1.1.时间格式化 yyyy-MM-dd HH:mm:ss格式&#xff0c;如下&#xff1a; select date_format(now(), %Y-%m-%d %H:%i:%s) from dual;date_format函数是将date类型按照指定的格式转换成varchar类型 1.2.日期加减 当前天 1 天 select date_format(now(), %Y-%m-%d), …

C语言数组和指针笔试题(一)(一定要看)

目录 一维数组例题1例题2例题3例题4例题5例题6例题7例题8例题9例题10例题输出结果 字符数组例题1例题2例题3例题4例题5例题6例题7 一维数组 int a[] {1,2,3,4}; 1:printf("%d\n",sizeof(a)); 2:printf("%d\n",sizeof(a0)); 3:printf("%d\n",si…

继续上一个爬虫,所以说selenium加browsermobproxy

继续&#xff0c;书接上回&#xff0c;这次我通过jsrpc&#xff0c;也学会了不少逆向的知识&#xff0c;感觉对于一般的网站应该都能应付了。当然我说的是简单的网站&#xff0c;遇到那些混淆的&#xff0c;还有那种猿人学里面的题目&#xff0c;还是免谈了。那种需要的水平太高…

Linux(Centos7)中安装Docker和DockerCompose

一、安装Docker Docker 分为 CE 和 EE 两大版本。CE 即社区版&#xff08;免费&#xff0c;支持周期 7 个月&#xff09;&#xff0c;EE 即企业版&#xff0c;强调安全&#xff0c;付费使用&#xff0c;支 持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频…

Mysql高级——存储引擎

存储引擎 1). 连接层 最上层是一些客户端和链接服务&#xff0c;包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于 TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程 池的概念&#xff0c;为通过认证安全接入的客户端提…

PY32F003F18之RS485通讯

PY32F003F18将USART2连接到RS485芯片&#xff0c;和其它RS485设备实现串口接收后再转发的功能。 一、测试电路 二、测试程序 #include "USART2.h" #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf() #include "…

C++之智能指针shared_ptr死锁问题(二百)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Nacos安装指南以及集群搭建

结合SpringCloud从基础到活用&#xff08;超详细&#xff09;查看 一、Windows安装 开发阶段采用单机安装即可。1.1.下载安装包 在Nacos的GitHub页面&#xff0c;提供有下载链接&#xff0c;可以下载编译好的Nacos服务端或者源代码&#xff1a;GitHub主页&#xff1a;https:…