我一直在使用AWS设置Serverless(.com),使用Bref (PHP layer)运行MPDF使用AWS Lambda和API Gateway将HTML转换为PDF。按照说明进行操作,..这是设置。
经过大量调试后,看来我可以:
-
在无服务器文件中添加
apiGateway
选项,但我总是遇到CORS问题(即经典的No 'access-control-allow-origin' header is present
)。我已经尝试了来自客户端/请求端的标头和来自服务器端的响应的每种组合(请参见下面的代码)。 -
或者,我无法使用
apiGateway
选项,如下所示,但随后我必须对我的身体进行base64编码(请参见$body = base64_encode($pdf);
),或者我得到了Bref错误指出The Lambda response cannot be encoded to JSON (...)
说一个人应该使用apiGateway
选项。
对主体进行编码很好,但是对于直接下载来说效果不佳,因为我需要对响应中的data
进行base64解码才能获得二进制数据。
帮助。
serverless.yml :(请注意已注释掉的apiGateway设置-了解更多原因)
service: html2pdf
provider:
name: aws
region: us-east-1
runtime: provided
stage: ${opt:stage,'dev'}
# apiGateway: ## <======= We talk about this below
# binaryMediaTypes:
# - '*/*'
# environment:
# BREF_BINARY_RESPONSES: 1
plugins:
- ./vendor/bref/bref
functions:
html2pdf:
handler: index.php
description: ''
timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
layers:
- ${bref:layer.php-73-fpm} #-fpm
events:
- http:
path: /html2pdf
method: post
cors: true
# Exclude files from deployment
package:
exclude:
- 'node_modules/**'
- 'tests/**'
index.php (在上面的yml文件中提到):
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use App\JsonParserMiddleware;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
$app = AppFactory::create();
$app->addMiddleware(new JsonParserMiddleware());
$app->post("/html2pdf",function (Request $request,Response $response) {
$data = $request->getParsedBody();
$payload = [];
$statusCode = 200;
if ($data['data'] == null) {
$payload['error'] = "HTML 64-bit encoded string is required";
return response($response,$payload,422);
}
$mpdf = new \Mpdf\Mpdf(['tempDir' => '/tmp']);
$mpdf->WriteHTML(base64_decode($data['data']));
$pdf = $mpdf->Output(null,"S");
$filename = $data['title'];
$body = base64_encode($pdf);
$response->getBody()->write($body);
$response->isBase64Encoded = true;
$response = $response
->withHeader("access-control-allow-origin","*")
->withHeader('access-Control-Allow-Credentials',"true")
->withHeader('Content-Type','application/pdf')
->withHeader('Content-Disposition',sprintf('attachment; filename="%s"',$filename))
->withStatus($statusCode);
return $response;
});
使用axios的客户端代码为:
let data = { data: <<some base64 encoded html string>>,title: "file.pdf" };
let options = {
headers: {
"Content-Type": "application/json",// "accept": "*/*",},}
let payload = {data : btoa(data),title:"contract.pdf"};
let url = "https://oli9w0wghb.execute-api.us-east-1.amazonaws.com/dev/html2pdf";
axios.post(url,payload,options)
.then(response => {
console.log(response.data);
});