Javascript 缓冲区中的Blob返回损坏的pdf

Javascript 缓冲区中的Blob返回损坏的pdf,javascript,pdf,puppeteer,Javascript,Pdf,Puppeteer,尝试使用Firebase函数上的Puppeter制作pdf:发送html片段,获取pdf 但是pdf已经损坏。我认为问题在于返回文件/缓冲区 //服务器: //设置 const func=require('firebase-functions'); const pptr=require(‘木偶演员’); const opts={内存:'1GB',区域:['europe-west3']}; const call=func.runWith(opts).https.onCall 让browser=pp

尝试使用Firebase函数上的Puppeter制作pdf:发送html片段,获取pdf

但是pdf已经损坏。我认为问题在于返回文件/缓冲区

//服务器:
//设置
const func=require('firebase-functions');
const pptr=require(‘木偶演员’);
const opts={内存:'1GB',区域:['europe-west3']};
const call=func.runWith(opts).https.onCall
让browser=pptr.launch({args:['--no sandbox']});
//onCall
exports.makePdf=调用(异步(数据)=>{
//这样就可以用{headless:false}打开页面测试了
const brws=await(await browser).createIncognitoBrowserContext();
const page=wait brws.newPage();
wait page.setContent(数据,{waitUntil:'domcontentloaded'});
const file=wait page.pdf({格式:'A4'});
等待brws.close();
//问题是返回文件
返回文件
});
文件
登录到服务器上时,它是一个缓冲区
,但当登录到客户端时,它是一个对象,在dec中,而不是十六进制
{data:{0:37,1:80,2:68,3:70,}

将其转换回缓冲区?转换回十六进制?哪个缓冲区

//客户端:
//发送html并接收文件
让html='Hi';
让文件=((等待fns.makePdf(html)).data;
//还尝试了buffer=newbuffer.from(JSON.stringify(file));
设blob=newblob(文件,{type:'application/pdf'});
//下载该文件
设a=document.createElement('a');
a、 href=window.URL.createObjectURL(blob);
a、 下载=`${name}.pdf`;
a、 单击();
或者pdf是否因为下载错误而损坏(
createObjectURL
)?或者onCall函数不能这样使用

关键是,我不知道为什么它不起作用。感谢您的帮助

我发现这与您的类似,并且我发现了一个不同之处,在缓冲区返回中,您需要指定头和HTTP代码,客户端浏览器可能误解了来自服务器的对象

这是另一个项目的返回段

constpdfbuffer=wait page.pdf({printBackground:true});
res.set(“内容类型”、“应用程序/pdf”);
资源状态(200)。发送(pdfBuffer);

代码中的所有内容看起来都是正确的,如果将PDF从dec转换为十六进制返回相同的字符串,我认为这可能是一个很好的解决方案。

好的/插入诅咒众神/

服务器: 所以可以使用onCall而不是onRequest,因为最终可以从json响应创建pdf。onCall更好一点的原因是,你不需要为COR或Header而烦恼,Google会为你做

//设置
const func=require('firebase-functions');
const pptr=require(‘木偶演员’);
const opts={内存:'1GB',区域:['europe-west3']};
const call=func.runWith(opts).https.onCall
//这在函数之外运行,因为它可能不会被终止
//如果连续快速调用该函数(在
//谷歌云功能(文档)
让browser=pptr.launch({args:['--no sandbox']});
//主要功能
exports.makePdf=调用(异步(数据)=>{
//准备好木偶演员,这样它就可以打印pdf了
const brws=await(await browser).createIncognitoBrowserContext();
const page=wait brws.newPage();
等待页面。设置内容(数据);
const file=wait page.pdf({
格式:“A4”,
打印背景:假,
边距:{左:0,上:0,右:0,下:0}
});
brws.close();
//然后返回小溪
返回文件
});
客户: 骗局在客户身上。我会加上评论

//这是在某个函数中,因为它需要异步
变量a、blob、缓冲区、d、文件、html、i、结果;
//这个html是用于测试的,它显然是以另一种方式收集的
html='Hi';
//我们从客户端调用函数
//fns是我在Google函数初始化中定义的速记对象
//它的字面意思是:f.httpscalable('makePdf'),其中f是函数对象
//您可以从初始化中获得
文件=((wait fns.makePdf(html))).data;
//由于onCall会自动换行,因此需要附加数据
//现在是重点
// 1. 将对象转换为数组
结果=[];(我在文件中){
d=文件[i];result.push(d);
}
// 2. 将其转换为Uint8Array
缓冲区=新的UINT8阵列(结果);
// 3. 创建一个blob,但缓冲区需要放入另一个数组中
blob=newblob([buffer],{type:'application/pdf'});
//最后,下载它
a=document.createElement('a');
a、 href=window.URL.createObjectURL(blob);
a、 下载=`${path}.pdf`;
a、 单击();

感谢您的回复。玩过之后,我发现
onCall
只能返回对象,这与您的观点非常相似,但配置错误的是服务器。所以我确实需要
onRequest
。但我得到了
错误:响应不是有效的JSON对象。
(在客户端!),即使我有
res.set('Content-Type','application/pdf')有什么想法吗?如果我有
res.status(200).send({data:file})那就好了,但我从
onCall
得到的东西是一样的;类似于JSON,而不是
res.set('Content-Type','application/pdf')和管道到一个Blob中会得到同样损坏的pdf。@n-smits如果您使用postman、curl或chrome直接命中函数(带有标题),它会工作吗?是的,成功。需要
let buffer=new Uint8Array(file.data)
然后
blob=new blob([buffer],{type:'application/pdf'})
在数组中
[buffer]