文章目录
前言
因为涉及文件权限,所以需要API二次包装后给客户端。
也就,不能让客户端直接链接读取。
比较坎坷,记录一下
一、文件流办法
API将PDF转文件流,传输给客户端
javascript
if (process.env.VUE_APP_PLATFORM === 'h5') {
// H5方案:生成Blob URL
const blob = new Blob([arrayBuffer], { type: 'application/pdf' });
this.pdfUrl = URL.createObjectURL(blob);
return;
}
H5还是很容易实现的。
APP就无法实现,plus.io.PUBLIC_DOCUMENTS、uni.env.USER_DATA_PATH都不能可用。读写网络一通配置还是报错。
二、PDFJS办法
https://mozilla.github.io/pdf.js/ 官网下载 按指示配置
static/
└── pdfjs/
├── build/
│ ├── pdf.js
│ └── pdf.worker.js
└── web/
└── viewer.html
javascript
<template>
<web-view :src="pdfViewerUrl"></web-view>
</template>
<script>
export default {
data() {
return {
pdfViewerUrl: ''
}
},
onLoad(options) {
const pdfUrl = decodeURIComponent(options.pdfUrl)
// 使用绝对路径指向static目录下的viewer.html,并传递PDF文件URL
this.pdfViewerUrl = `/static/pdfjs/web/viewer.html?file=${encodeURIComponent(pdfUrl)}`
}
}
</script>
但是调试问题很多啊:
1、file origin does not match viewer's(跨域)
2、Failed to load module script" 错误(MIME 类型)
搞不定
三、uniapp插件办法
在插件市场找到个可以用的,自己改了改
csharp
public static string pdf(string path,string uid)
{
try
{
string filename = $"tmp_{uid}.pdf";
string topath = $"wwwroot\\pdf\\{filename}";
string directoryPath = Path.GetDirectoryName(topath);
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
File.Copy(path, topath, true); // 第三个参数表示覆盖已存在的文件
return "true";
}
catch (Exception ex){
return "nosrc";
}
}
后端C#,将pdf 挪个窝,移到webapi临时文件。
csharp
<template>
<view>
<!-- PDF容器 -->
<ss-preview :fileUrl="fileUrl" :fileType="fileType" :imageList="imageList"></ss-preview>
</view>
</template>
<script>
export default {
data() {
return {
fileUrl: '',
fileType: '2',
imageList: [],
};
},
onLoad() {
let uid=this.$assist.gdata("user").id;
let src =this.$mConfig.baseUrl+ `/pdf/tmp_${uid}.pdf`;
let fileUrl = decodeURIComponent(src)
this.fileUrl = fileUrl;
},
onNavigationBarButtonTap(e) {
this.navTo('scan');
},
onBackPress(options) {
this.navTo(this.$assist.gdata("mypage"))
// 阻止默认返回行为
return true;
},
methods: {
async navTo(url) {
this.$mRouter.push({
route: url
});
},
},
};
</script>
然后UNIAPP里直接读取 PDF就行。安卓测试成功。
缺点就是 这控件的渲染太快,我干脆在点击链接的时候触发后端,复制完后回传bool,前端再跳PDF页面显示
不知道v-if 能解决这问题不。

四、补充
虽然PDF显示没问题了,API中的临时PDF是根据用户名区分,
即解决了,多用户冲突问题,也不会导致文件很多的情况。
但是也衍生了一个问题,访问 A.PDF 或 B.PDF,他们的临时路径都是 API\tem_0.pdf ,缓存会导致页面内容不会刷新 。这就需要加一个临时版本号:
javascript
let src =this.$mConfig.baseUrl+ `/pdf/tmp_${uid}.pdf`;
改为
let src =this.$mConfig.baseUrl+ `/pdf/tmp_${uid}.pdf?t=` + new Date().getTime();
// this.$mConfig.baseUrl= http://localhost:8090/ 就是我的WebApi地址
/*
Webapi的 Program.cs 别忘了加入下面的代码,打开静态文件
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")),
});*/