文档预览
文档预览 是在文档 格式转换 基础上提供的功能,通过将输入文档转换为 JPG
、 PNG
等输出格式,您可以快速搭建自己的文档预览。
同时,智能媒体管理服务推荐您使用 VECTOR
输出格式,然后通过智能媒体管理提供的前端渲染引擎,实现更易用、功能更强大、定制化的文档预览效果。
下面重点跟大家讲解向量模式 VECTOR
的文档预览实现。
1. 预览原理
- 上传需要预览的文件存储在对象存储 OSS 中。
- 调用智能媒体管理的 文档格式转换 接口,将要预览的源文件按转换为向量格式输出到指定的 OSS 目录。
- 将智能媒体管理提供的预览引擎:
preview.imm.aliyuncs.com/index.html?url=[TgtUri]
通过HTML
的<iframe>
标签嵌入到用户自己的页面或者 Web App 中进行文档预览。其中TgtUri
为预览文件在 OSS 的 http(s)路径,需要通过 QueryString 参数传入,如下图所示:
2. 准备工作
(1) 跨域配置
由于被访问的 OSS Bucket 域名同上述预览引擎的域名不同,所以直接访问会存在跨域问题。此时用户需要在 OSS 控制台 将预览服务域名添加到存储转换后文档 OSS Bucket 的跨域访问列表中,具体操作路径为: OSS 控制台 -> 基础设置 -> 跨域设置 -> 创建规则
,需要创建的跨域规则如下图:
(2) OSS临时授权访问
由于预览引擎需要从用户的 OSS Bucket 读取转换后的文档,受用户 Bucket 读取权限(了解 OSS 读写权限控制)影响,预览引擎读取文档方式也不尽相同。
公共读
如果 Bucket 设置为公共读,则此 Bucket 中的所有文件无需任何授权即可读取,无需传入访问凭证相关的参数即可预览,设置公共读前请确认是否有相关安全风险。
私有读
此时需要通过 OSS STS 获取该文件临时的访问权限,获取临时访问凭证之后传递给预览引擎,预览引擎通过凭证获取相关权限,从而实现文档预览。临时访问凭证一般包括
AccessKeyId | AccessKeySecret | SecurityToken
,如何获取临时访问权限,请参考STS临时授权访问OSS。
3. 预览引擎
(1) 预览接入方式介绍
预览引擎支持两种预览方式:
1. URL 参数预览
2. JavaScript API 预览
两种方式的优缺点对比如下:
方式 | 优点 | 缺点 |
---|---|---|
URL 参数预览 | 快捷方便 | 相关临时授权凭证会暴露在 iframe 的 URL 地址上 |
JavaScript API 预览 | JavaScript API 隐式传递参数,安全性较高 | 需要部分额外的前端编程工作 |
URL 参数预览的优点是方便,但容易暴露预览地址。当用户 bucket 为私有读并在签名有效期内,用户只要把对应的 URL 从 iframe src
属性中复制出来即可分享给别人,对安全性要求较高的业务不建议这种方式。通过 JavaScript API 传递参数的方式,由于 iframe 地址不含签名,因此用户即使复制了 URL 也无法预览。用户可根据应用场景自行选择预览方式,推荐使用 API 方式。
下面分别介绍两种预览的具体实现。
(2) 方式一: URL 参数预览
URL参数预览即通过 URL QueryString 将必要的参数传递给预览引擎,预览引擎获取相关参数后在页面上展示出文档,一个完整的预览 URL 格式如下所示:
https://preview.imm.aliyuncs.com/index.html?url=[url]&accessKeyId=[accessKeyId]&accessKeySecret=[accessKeySecret]&stsToken=[stsToken]&bucket=[bucket]®ion=[region]
其中 https://preview.imm.aliyuncs.com/index.html
是智能媒体管理服务提供的预览引擎地址,?
后面的参数是预览文档的信息,如果不提供必须的参数,则会预览失败。
预览 URL 示例
https://preview.imm.aliyuncs.com/index.html
?url=https://yourid-dev-imm.oss-cn-shanghai.aliyuncs.com/paxos.pptx/output //转换结果地址,无需在output后加'/'
&accessKeyId=STS.AAAA //STS 返回的 AccessKeyId,注意 access 小写
&accessKeySecret=BBBB //STS 返回的 AccessKeySecret,注意 access 小写
&stsToken=CCCC //CCCC 是 encode(STS返回的 SecurityToken)得到的结果,不直接使用
®ion=oss-cn-shanghai //转换数据所在桶的 region,注意加 oss 前缀
&bucket=bucket-name //转换数据所在桶
&...
参数解释
参数名 | 类型 | 是否必填 | 描述 |
---|---|---|---|
url | String | 是 | 文档格式转换后的向量文件所在目录, 注意:无需在目录后加/ |
region | String | 私有读时必填 | OSS 数据所在region,例如oss-cn-shanghai, 注意:添加 OSS 前缀 |
accessKeyId | String | 私有读时必填 | 从 STS 获取的访问 OSS 参数 |
accessKeySecret | String | 私有读时必填 | 从 STS 获取的访问 OSS 参数 |
stsToken | String | 私有读时必填 | 从 STS 获取的访问 OSS 参数 |
bucket | String | 私有读时必填 | OSS 数据所在桶 |
endpoint | String | 否 | 使用与 OSS 桶绑定的用户域名进行预览,使用此参数时无需传递 bucket 和 region |
pageIndex | Int | 否 | 从指定的页码开始预览 |
serverTime | Int | 否 | 服务器当前时间,单位:秒,用于校准本地 OSS 签名时的时间,避免本地与服务器时差大于 15min 导致签名失败 |
expires | Int | 否 | 文档预览有效时间,单位:秒,默认:1800 |
注意事项:
- 其中参数 url 格式同 OSS 实际访问地址,如
https://yourid-dev-imm.oss-cn-shanghai.aliyuncs.com/paxos.pptx/output
,结尾无需加上/
(3) 方式二: JavaScript API 预览
JavaScript API 预览具有更好的安全性,并且提供了高级功能的配置(详见下一章文档预览JavaScript API),JavaScript API 本质上通过 postMessage
将必要参数发送给预览引擎页并完成初始化工作,postMessage
的浏览器兼容请参考 此链接.
JavaScript API 预览 Demo 如下:
<html>
<head>
<meta charset="UTF-8">
<!-- 建议禁用外框浏览器自带的缩放 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<style>
* {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
height: 100%;
/* 防止双击缩放 */
touch-action: manipulation;
}
.main {
display: flex;
flex-direction: column;
height: 100%;
}
#aliyunPreview {
flex: 1;
}
</style>
<script type="text/javascript" charset="utf-8">
function json2str(obj) {
return JSON.stringify(obj, function(key, val) {
if (typeof val === 'function') {
val = val.toString();
}
return val;
});
};
window.sendMessage = function(action, data) {
var iframe = document.getElementById('aliyunPreview');
iframe.contentWindow.postMessage(json2str({ action: action, data: data }), '*');
};
window.addEventListener('message', function(e) {
try {
var res = JSON.parse(e.data);
} catch(err) {
return;
}
switch (res.action) {
case 'preview.ready':
window.sendMessage('preview.init', {
url: '',
region: '',
bucket: '',
accessKeyId: '',
accessKeySecret: '',
stsToken: ''
});
break;
}
}, false);
//禁止双指缩放手势
document.addEventListener('gesturestart', function (e) {
e.preventDefault();
});
</script>
</head>
<body>
<iframe
allowfullscreen
id="aliyunPreview"
frameborder="0"
src="https://preview.imm.aliyuncs.com/index.html"
></iframe>
</body>
</html>
初始化流程
为便于描述,以下称阿里云的 iframe 页面为子页面,嵌入该 iframe 的接入方页面称为父页面;
- 子页面发送 preview.ready 事件;
- 父页面接收 preview.ready 事件之后,发送 preview.init 事件以及传递初始化参数;
- 子页面接收 preview.init 事件及其参数,并以此初始化渲染引擎;
事件说明
父页面向子页面发送消息,通过 sendMessage(参考上面demo)完成,调用格式为:sendMessage(action, data)
参数名 | 类型 | 是否必填 | 描述 |
---|---|---|---|
action | String | 是 | 事件名称 |
data | Object | 否 | 事件参数 |
其中 action 可使用如下定义:
- preview.init:父页面传递初始化子页面参数,可设置参数列表如下:
参数名 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
url | String | 是 | - | 文档格式转换后的向量文件所在目录, 注意:无需在目录后加/ |
region | String | 私有读时必填 | - | OSS 桶所在区域 |
bucket | String | 私有读时必填 | - | OSS 桶的名称 |
accessKeyId | String | 私有读时必填 | - | OSS 桶访问的钥匙 ID |
accessKeySecret | String | 私有读时必填 | - | OSS 桶访问的钥匙 Secret |
stsToken | String | 私有读时必填 | - | OSS 桶访问的令牌 |
endpoint | String | 否 | - | 使用与 OSS 桶绑定的域名,使用此参数时无需传递 bucket 和 region |
copy | Int | 否 | 0 | 是否允许文字拷贝,可选值[0, 1],0 - 禁止, 1 - 允许 |
wmType | Int | 否 | 0 | 水印类型 可选值[0, 1, 2],0 - 关闭水印 1 - 文字水印 2 - 图片水印 |
wmValue | String | 否 | - | 水印值,wmType 为 1 时,水印内容,wmType 为 2 时,图片水印地址 |
wmColor | String | 否 | rgba(192, 192, 192, 0.6) | 水印颜色,RGBA值 |
wmRotate | Float | 否 | -Math.PI / 4 | 水印角度 |
wmFont | String | 否 | bold 20px Serif | 水印字体 |
wmHeight | Int | 否 | 170 | 水印高度 |
wmWidth | Int | 否 | 195 | 水印宽度 |
- setConfig:父页面设置子页面相关的渲染参数,具体支持的功能详见下一篇: 文档预览JavaScript API.
- setData:用于传递参数变量,供 setConfig 中使用,函数中的变量以 window.iframeData 形式在子页面中访问,可多次调用。
sendMessage("setData", {
// 需要在子页面中用到的数据
});
4. 预览页面提示错误码
错误码 | 描述 |
---|---|
-1002 | 无效的 AccessKeyId |
-1003 | 无权限访问该文档 |
-1004 | 无效的 STSToken |
-1005 | STSToken 已过期 |
-1006 | 签名错误 |
-1007 | Bucket 未配置跨域 |
-1008 | Refers 配置错误 |
-1100 | 其他原因造成的错误 |
5. 支持的浏览器
- Internet Explorer 10+ and Microsoft Edge
- Google Chrome
- Firefox
- Safari
- Opera
6. 常见问题以及解决方案
声明: 以下方案仅为建议的通用解决方案,不保证百分百适用所有场景,不同的应用场景需要具体问题具体分析
iframe内部预览界面被遮挡问题
- 禁止iframe滚动,设置iframe属性
scrolling="no"
(预览界面实现了局部滚动,可以放心把该属性设置为no) - 通过flex布局来给iframe弹性高度或者通过js计算设置iframe一个具体高度值,不能用百分比
- 禁止iframe滚动,设置iframe属性
父级窗口缩放导致预览界面变形问题怎么处理? 遇到此问题则需要父级窗口禁用浏览器自带的缩放功能
- 安卓下解决方案
安卓下通过设置viewport的user-scalable属性来禁止父级窗口缩放
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
- iOS下解决方案
禁用双击缩放手势
body {
touch-action: manipulation;
}
禁止双指缩放手势
document.addEventListener('gesturestart', function(e) {
e.preventDefault();
});
PPT预览全屏按钮在某些浏览器中消失如何处理?
出现此问题时,您只需在 iframe 上添加
allowfullscreen
属性即可修复,加上此属性后PPT文件可支持全屏预览。IE 下通过
location.href | window.open
打开预览URL时,如果URL中包含复制功能参数©=1
,则会被当做 HTML 实体解析为版权符号©=1
,导致预览不成功怎么处理?这个问题是由于 IE 的经典bug导致,此时有两种解决方案:
- 判断如果在 IE 浏览器中,在跳转前把
&
转义为 HTML字符实体&
- 将
©=1
位置调整为紧跟 url 的第一个参数,如?copy=1&...
即可解决,推荐第二种方法较快捷。
- 判断如果在 IE 浏览器中,在跳转前把
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。
评论