javascript - iFrame + PDF.js + puppeteer - 生成和显示 PDF 文件的好组合?
问题描述
从星期一开始,我尝试找到正确的方法来快速安全地生成和显示 PDF 文件,其中包含以下内容 - 也许我只是感到困惑或盲目地看到答案:
Apache - 为我的实际项目运行我的 PHP 脚本(端口 443) NodeJS - 运行单个脚本以从 HTML 生成 PDF 文件(端口 8080)
我需要什么:确保允许用户生成和查看 PDF。让查看器栏(如屏幕截图所示)可用对我来说很重要。
有一个 cookie,其中存储了 Session-Hash,并且用户在每个请求上都在其上进行身份验证(例如通过 AJAX)。
完整过程的描述:在我的项目的一页上显示了一个 iFrame。这是一个 PDF 查看器(来自 PDF.js),它周围有一些按钮: 在一切开始之前的状态
单击左侧的按钮(名为“加载 PDF 1”,...)会触发以下事件:
$(document).on("click", ".reportelement", function () {
//some data needs to be passed
let data = "report=birthdaylist";
//point iFrame to a new address
$("#pdfViewer").attr("src", "https://example.org/inc/javascript/web/viewer.html?file=https://example.org:8080?" + data);
});
此时,iFrame 将重新加载查看器,该查看器接受 GET 参数并执行它:
https://example.org/inc/javascript/web/viewer.html?file=https://example.org:8080?" + data //sends the data to the NodeJS script and recieves PDF
==> ?file=https://example.org:8080 //GET... it's bad... How to do a POST in iFrame?!
所以,看看 NodeJS Script(我不得不说我对 async 和 NodeJS 不是很熟悉):
const https = require("https");
const fs = require("fs");
const puppeteer = require('puppeteer');
const url = require("url");
var qs = require('querystring');
const request = require("request-promise");
const options = {
key: fs.readFileSync("key.pem", "utf-8"),
cert: fs.readFileSync("cert.pem", "utf-8"),
passphrase: 'XXXXXXXX'
};
https.createServer(options, function (req, res) {
(async function () {
if (req.method == 'POST') {
var body = '';
req.on('data', function (data) {
body += data;
// Too much POST data, kill the connection!
// 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
if (body.length > 1e6)
req.connection.destroy();
});
req.on('end', function () {
//got a selfsigned certificate only, will change it soon!
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
(async function () {
var result = await request.post('https://example.org/index.php', {
//htpasswd secured at the moment
'auth': {
'user': 'user',
'pass': 'pass',
'sendImmediately': false
},
//i would like to send the cookie oder the hash in it
//or something else to it ensure, that the user is allowed to
form: {
giveme: 'html'
}
},
function (error, response, body) {
//for debugging reasons
console.log("error: " + error);
console.log("response: " + response);
console.log("body: " + body);
}
);
const browser = await puppeteer.launch();
const main = async () => {
//generating pdf using result from request.post
}
const rendered_pdf = await main();
res.writeHead(200, {
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
"Access-Control-Allow-Origin": "*",
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment; filename=mypdf.pdf',
'Content-Length': rendered_pdf.length
});
res.end(rendered_pdf);
})();
});
} else if (req.method == 'GET') {
console.log("we got a GET");
} else {
console.log("we got NOTHING");
}
})();
}).listen(8080);
一切正常,PDF 显示良好 - 但正如我之前提到的,我不知道如何确保允许用户生成和查看 PDF。
tldr;
有没有办法(可能没有 iFrame)来保护用户被允许?让查看器栏(如屏幕截图所示)可用对我来说很重要。
解决方案
推荐阅读
- javascript - JavaScript | 数组重复
- pyspark - Pyspark Dataframes Resolved attribute(s) 错误,没有匹配的列名
- python - 如何使用 xml.etree.ElementTree Python 格式化属性、前缀和标签
- ember.js - 错误:“ReferenceError:pauseTest 未定义”在使用 moduleForComponent 语法的集成测试中
- c - 如何解决此 C 程序中的类型重新定义错误
- json - Pandas read_json value_error, Type_erroe
- java - 使用 GridFs 存储大型 Mongo 文档
- verdaccio - 无法使用 Verdaccio 查看或发布包
- java - 在 Java/Kotlin 中通过可重复的分隔符拆分字符串
- java - 设置 JPA 实体的问题(Spring Boot)