☰
ONLYOFFICE在线文档预览:Docker部署+一个HTML文件快速搞定
2026/9/28 22:41:09 网站建设 项目流程

接到“做个在线预览文档”的需求时,我的第一反应不是写代码,而是先回答几个问题:谁来解析文档?预览界面长什么样?要不要动后端?如果你和我一样,既不想给用户装Office,又懒得自己开发一套解析引擎,那ONLYOFFICE几乎是绕不开的选项。

它是开源的文档处理服务,支持Word、Excel、PPT、PDF这些常见格式,也带在线协同编辑能力。而今天的demo更简单粗暴——只需要一个index.html文件,双击它就能直接在浏览器里预览文档。这个demo我已经实际跑通,整个过程从部署到打开页面,大概只要半小时。适合刚收到文档预览需求、想做技术验证的开发者,也适合正在选型的团队拿去做快速演示。它不需要编译、不需要前端框架,你只要部署一个文档服务,再把页面打开,能跑通就说明整套方案可以落地。

下面我就从选型、部署、代码到常见问题,把这个demo的完整链路讲清楚。

1. 选型背后的思考:为什么是ONLYOFFICE

1.1 先摆出几个我可以考虑的方案

我在接到文档预览需求时,眼前的选项其实不少。放在当前的技术语境里,大致有四条路可走:

方案优点缺点
让用户下载原始文件零开发成本体验极差,用户手机里甚至没有能打开的软件
后端转成PDF再预览实现简单,浏览器原生支持动态文档不友好,交互和权限很弱,转码还有延迟
用WPS/微软的Web组件功能完整,接入方便商业化授权复杂,私有化部署受限
ONLYOFFICE自托管格式还原度高、开源、可私有化部署部署有门槛、内存消耗大、前端API需要读文档

我见过很多团队在方案一和方案二之间纠结,最后因为给客户演示时效果太差而放弃。转PDF的方式适合“看一眼”的场景,但遇到Word里复杂排版、Excel里多工作表、PPT里动画特效,损失的信息会多到让业务方直接摇头。ONLYOFFICE能在浏览器里尽量还原原始文档的版式和交互,还允许你控制下载、打印、批注这些细粒度权限,这是它最大的价值。

1.2 demo的整体设计

整个demo走的是“前端嵌入式+远程解析服务”的骨架。ONLYOFFICE Document Server装在Docker里,负责格式解析、渲染、缓存和格式转换;index.html通过官方提供的api.js与Document Server交互。前端完全不用关心文件是怎么从docx变成可预览网页的,后端也不用把文件解析细节暴露给业务方,两边只约定一个JSON配置就可以。

这么设计还有一个好处:组件边界清晰。你完全可以在不改动任何后端逻辑的前提下,把这个demo嵌入到自己系统的任意一个页面里。只要你的文档地址能通过HTTP访问,ONLYOFFICE就能在iframe里把它渲染出来。对于OA系统、网盘系统、工单系统这种三天两头要“在线打开附件”的场景,这种架构特别省心。

1.3 为什么非要做成“双击index.html”这种形式

我特意把demo做到“双击就能看效果”,不想引入Node、Nginx或者构建工具链。原因很直接:文档预览这个需求,真正的复杂度在服务端部署和API配置上,前端调用反而很简单。如果demo一开始就拉起一个Vue或React项目,很多人会分不清哪些代码是ONLYOFFICE的、哪些是业务框架的,出了问题根本不知道去哪里定位。

一个空白的index.html,把所有注意力都留在纯API调用上。你双击它,打开浏览器F12,一眼就能看清页面请求了哪些资源、Document Server返回了什么。这对理解整个预览机制非常有帮助,也是我推荐所有新手从这个形式入手的原因。

2. 环境准备:用Docker把文档服务跑起来

2.1 一条命令启动文档服务器

ONLYOFFICE官方提供了文档服务器镜像,部署方式对新手极其友好。我下面的命令就是实际测试可用的:

docker run -d \ --name onlyoffice-docserver \ --restart=always \ -p 8080:80 \ -e JWT_ENABLED=true \ -e JWT_SECRET=my-secret-key \ onlyoffice/documentserver:latest

简单解释一下几个关键点:

  • -p 8080:80把容器的80端口映射到宿主机的8080,你通过http://127.0.0.1:8080访问文档服务。
  • JWT_ENABLED=true开启了接口签名验证,防止预览接口被外部随意调用。
  • JWT_SECRET是签名密钥,生产环境一定要换成足够长的随机字符串,别用demo里的示例值。
  • 镜像拉取需要一点时间,大概几百MB到1GB,取决于网络环境。

启动后可以用docker logs -f onlyoffice-docserver看启动日志,看到server started类似输出,就说明核心服务已经起来了。

注意:生产环境建议固定镜像版本,不要用latest跟着漂。不同大版本之间的API有差异,尤其是JWT、缓存目录、配置结构这些都可能变。

2.2 启动后如何自检

服务跑起来后,打开浏览器访问http://127.0.0.1:8080/welcome,如果能看到ONLYOFFICE欢迎页,说明文档服务本身没有问题了。

但注意,这只代表服务在线,不代表它能预览你的文件。真正能预览还要看后面几步,比如文件URL是否可达、跨域配置是否正确、JWT是否通过。很多人卡在“服务是通的,但页面就是白屏”,其实是排错了方向。

2.3 权限、JWT和跨域,一次说清楚

ONLYOFFICE从7.2版本开始默认开启JWT验证,客户端传给它的config对象必须携带有效签名,否则请求会被拒绝。关闭JWT确实可以让单纯的demo更简单,但关闭后任何人都能调用你的文档服务消耗资源,局域网自测可以,线上千万别这么干。

如果你用Node做后端,生成token的方式很简单,用官方推荐的jsonwebtoken库:

const jwt = require('jsonwebtoken'); const config = { document: { title: '示例文档.docx', url: 'http://your-server.com/files/sample.docx', fileType: 'docx' }, documentType: 'word' }; const token = jwt.sign(config, 'my-secret-key', { algorithm: 'HS256', expiresIn: '1h' }); config.token = token;

这个token的内容是整个config对象,签名用的密钥必须和容器里的JWT_SECRET一致。ONLYOFFICE收到请求后会用同样的密钥验签,验签通过才放行。

跨域方面,因为我们是直接双击index.html打开的,浏览器给Document Server发起的请求属于跨域请求,而且file://协议下Origin是null,Document Server默认会拒绝。本地调试时可以在容器里调整配置文件/etc/onlyoffice/documentserver/local.json:

{ "services": { "CoAuthoring": { "requestFilteringAgent": { "allowOrigin": ["*"] } } } }

改完重启容器:

docker restart onlyoffice-docserver

生产环境千万别把allowOrigin设成*,老老实实改成你业务系统的真实域名。更稳妥的做法是用Nginx反向代理,让前端页面和文档服务处在同一个域名下,彻底避开跨域。

3. 核心代码:index.html 与 ONLYOFFICE API 的接入方式

3.1 一个能直接双击打开的index.html

下面这个文件就是我demo的全部前端代码。我直接把文件扔到桌面,双击就能在默认浏览器里打开预览效果。

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>ONLYOFFICE 文档预览 Demo</title> <!-- API 样式文件,不引入会影响布局 --> <link rel="stylesheet" type="text/css" href="http://127.0.0.1:8080/web-apps/apps/api/documents/api.css"> <!-- 核心 API 文件 --> <script type="text/javascript" src="http://127.0.0.1:8080/web-apps/apps/api/documents/api.js"></script> <!-- 开启 JWT/签名校验时需要,如果页面报 cryptosign 未定义就补上这行 --> <script type="text/javascript" src="http://127.0.0.1:8080/web-apps/apps/api/documents/cryptosign.js"></script> </head> <body> <!-- 预览容器,ONLYOFFICE 会把这个 div 替换成可交互的预览区域 --> <div id="docPreview" style="width:100%;height:800px;"></div> <script type="text/javascript"> var docEditor = new DocsAPI.DocEditor("docPreview", { "document": { "fileType": "docx", "key": "demo_2025_001", "title": "示例文档.docx", "url": "http://your-server.com/files/sample.docx", "permissions": { "download": true, "edit": false, "print": true } }, "documentType": "word", "editorConfig": { "lang": "zh-CN", "mode": "view", "customization": { "autostart": false, "display": "view", "compactToolbar": true } }, "height": "100%", "width": "100%", "type": "desktop" }); </script> </body> </html>

代码里最需要注意的就是document.url。ONLYOFFICE的Document Server会主动去这个地址拉取文件,而不是把文件内容直接塞给前端,所以这个URL必须是Document Server能访问到的地址。本地测试时可以放一份sample.docx到Nginx静态目录下,让Document Server通过HTTP访问。

我第一次做demo时把url写成了file:///C:/xxx/sample.docx,结果Document Server在Linux容器里根本访问不到宿主机路径,页面一直转圈。后来改成HTTP地址,问题立刻消失。

3.2 最容易搞混的配置字段:document、documentType、editorConfig

很多新手第一次接触ONLYOFFICE API时会困惑,为什么同时有fileType和documentType这两个字段?它们分工其实很清晰:

  • documentType是文档的大类,影响前端加载哪套编辑器界面,取值只有word、cell、slide、pdf。
  • fileType是具体文件格式,比如docx、xlsx、pptx、pdf,它告诉Document Server用哪个解析组件去处理文件。

不同格式和文档类型的对应关系可以参考下表:

documentTypefileType 示例主要格式
worddocx、doc、odt、rtf、txt文字类文档
cellxlsx、xls、ods、csv表格类文档
slidepptx、ppt、odp演示类文档
pdfpdfPDF文件,直接走专用查看器

editorConfig.mode也很关键。demo里设置成view,用户就只能预览不能编辑,适合做“在线查看附件”这种场景。如果你确实需要在线编辑,就把它改成edit,同时还要在editorConfig里配置callbackUrl,否则Document Server不知道把编辑结果回传到哪个地址。

permissions里能控制打印、下载、批注等操作按钮的显隐。这里面download和print是业务方最在意的,日常需求基本都是“只让看,不让带走”。

3.3 三种嵌入场景怎么选

ONLYOFFICE的嵌入方式其实不只一种,这取决于你的使用场景。我简单列一个对照表:

场景推荐方式关键参数
纯前端静态demo静态config+固定文档URLdocument.url固定,key可写死
业务系统(有后端)服务端动态生成config和JWTkey用文档内容hash,token每次动态签发
页面角落内嵌type设置为embedded隐藏工具栏,只保留内容区域

大多数正式项目都应该走第二种。因为业务系统里文档是不断更新的,如果你一直用同一个key,Document Server会命中缓存,用户看到的就是旧文档。很多人在集成时发现“改了文件内容但预览没变化”,就是key没跟着变。

我后来在公司项目里把这个demo改成Vue3组件,发现核心代码几乎没变,无非是把new DocsAPI.DocEditor放进onMounted,销毁时调用docEditor.destroy()。所以这个原生HTML版本的demo,反而是理解ONLYOFFICE集成最直接的入口。

4. 底层逻辑:ONLYOFFICE是怎么把文档渲染到网页里的

4.1 两套预览路径:Office类文档和PDF

ONLYOFFICE的预览逻辑其实分两条完全不同的路径,理解它能让你排查问题快很多。

Office类文档(docx、xlsx、pptx等)走的是编辑器内核。Document Server启动时会解析文档内容,把版式、样式、图片、表格这些信息转换成前端所需的渲染数据,再通过web-apps渲染成网页。整个解析过程对前端透明,你只管拿到渲染完成后的页面。

PDF走的是另一条路。Document Server直接加载PDF文件,由前端专用查看器组件渲染,documentType设为pdf即可。PDF路径不涉及文档解析和格式恢复,所以响应速度和资源占用都比Office路径轻。

这也解释了为什么用ONLYOFFICE预览Word文档时,偶尔会出现和Office本地渲染不完全一致的现象。它毕竟是自研内核做解析,不是把Office装到服务器里。如果你追求的只是“看个大概”,完全够用;如果要拿它做像素级排版校对,那需要做更多配置和取舍。

4.2 api.js、api.css和cryptosign.js,到底哪几个脚本是必须的

接入ONLYOFFICE时,页面里必须引入的文件其实就两个:api.css和api.js。前者负责预览区域的基础样式,后者提供DocsAPI.DocEditor这个核心入口。

如果你在文档服务器上开启了JWT验证,部分版本还要求引入cryptosign.js,否则初始化时会报错提示缺少签名模块。.js文件的加载顺序有讲究,api.js要在你调用DocsAPI.DocEditor之前加载完成,所以我把所有script标签都放在了正文开头,避免异步加载顺序导致“DocEditor is not defined”。

这类前端脚本本身很小,它只是一个启动器。真正的渲染资源是在你调用初始化方法后,Document Server动态返回的,所以第一次加载预览页面会明显慢一点,这是正常现象,不是死循环。

4.3 document.key这个“小参数”背后的缓存逻辑

key真的是整个config里最容易被忽略的参数。它的作用是让Document Server按key缓存已经解析过的文档。同一个key在有效期内重复请求,Document Server直接用缓存,能大幅节省服务器性能。

但缓存是把双刃剑。文档内容变了,key不变,用户预览到的还是旧版本。生产环境里我建议把key设计成“文档ID + 内容哈希 + 版本号”的组合,内容每变一次,key就换一次。这才是稳妥的做法。

我见过一个网盘系统,所有文档都用同一个固定key,结果所有用户打开的都是同一个人上传的第一份文件。这个问题排查起来特别隐蔽,因为页面不是报错,只是内容完全不对。

5. 常见问题与排查技巧实录

5.1 最常见的问题速查表

把我在实际使用中和网上看到的高频问题整理了一下,大家可以直接对照排查。

现象可能原因排查方向
页面白屏Document Server启动失败、跨域被拒、URL不可达先访问welcome页确认服务在线,再看F12网络请求状态码
控制台报domain is not allowedCORS配置不对,请求Origin不在允许列表检查local.json的allowOrigin,本地调试可先设为*
文档一直转圈加载document.url不可达、JWT签名错误、缓存损坏直接在浏览器打开document.url试试;清空Persistent Cache
提示JWT验证失败token过期、密钥不一致、token未生成检查JWT_SECRET,确认token用HS256签名,过期时间别太短
PDF无法预览documentType配置成了wordPDF要单独使用documentType: "pdf"
文档被锁定无法编辑同一文档被其他人用同一个key打开修改key,或确认mode是view
预览到了旧文档key没有随文档内容变化将key设计为内容哈希,文档更新后强制换key

5.2 我踩过最有代表性的坑

第一个坑就是前文提到的localhost坑。Document Server在Docker容器里运行,容器里的localhost指向容器自己,不是宿主机。所以document.url里写http://localhost:8080/files/sample.docx时,Document Server去访问的是容器内的8080,结果当然失败。解决方法是把URL改成宿主机在局域网内的IP,比如http://192.168.1.100:8080/files/sample.docx。

第二个坑是双击index.html时,浏览器以file://协议打开页面,Origin是null。ONLYOFFICE的跨域校验会把这种请求直接拒掉。本地调试需要放宽CORS配置,线上则要用Nginx反代,让前端页面和文档服务同域。我一开始在这块花了很长时间,因为报错信息是英文,而且不明显。

第三个坑是内存。ONLYOFFICE文档服务对内存要求不低,官方建议至少2GB,我实际跑下来,同时解析几个大文档时4GB都紧巴巴。如果你是在1GB的小机器上做demo,经常会出现预览到一半服务崩溃。解决办法是在docker启动时限制容器资源,或者干脆换一台配置高一点的机器。

5.3 批注、历史修改记录、打印控制还能怎么玩

很多人搜“api怎么取onlyoffice批注”“代码查看历史修改记录”,其实这些能力不是纯前端能拿到的。ONLYOFFICE默认的预览模式只是展示渲染结果,要拿到批注数据、协同编辑动态、历史版本,必须进入编辑模式,并在服务端配置callbackUrl回调接口。

以批注为例,流程大致是:用户在预览页添加批注之后,ONLYOFFICE会在某个时间点把文档状态回调到你的后端接口,你需要在接口里解析回调数据,提取批注对象和位置信息。单纯在前端用DocsAPI.DocEditor是拿不到这些数据的。所以如果你想在业务系统里做“文档批注回传”“历史版本管理”“协同编辑记录”这类功能,demo之外还需要一套后端回调服务。

打印控制则相对简单,直接在permissions里把print设为false,工具栏的打印按钮就会隐藏。但注意,这只隐藏按钮,用户还是可以通过浏览器自带的打印功能去打印,想彻底封死打印,就得在后端做水印、内容加密这些额外手段。

6. 写在最后:demo跑通只是起点

这个demo我前后用了差不多两天才把它跑得顺手,最大的感受是:把最复杂的东西先交给ONLYOFFICE,自己专注在前面这层“壳子”上。Document Server解决了解析、渲染、缓存、权限、协同这些硬骨头,业务系统只需要管好文档存储、URL生成和权限校验。

如果你要把这个demo落地成真实功能,建议把JWT和key的设计提前做好。JWT保证只有自己系统能调用预览服务,key保证用户不会看到陈旧文档。这两件事看起来是后端的事,但前端不提前留好传参位置,后面改起来会特别别扭。

另外,在给客户或领导演示之前,一定用一份真实的复杂文档先跑几轮,别拿hello world测试。Word里的分节符、Excel里的透视表、PPT里的内嵌动画,这些才是真正考验渲染质量的地方。跑通了,方案就算真正立住了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询