Serverless,Bref PHP和Slim的二进制响应得到CORS或base64编码

我一直在使用AWS设置Serverless(.com),使用Bref (PHP layer)运行MPDF使用AWS Lambda和API Gateway将HTML转换为PDF。按照说明进行操作,..这是设置。

经过大量调试后,看来我可以:

  1. 在无服务器文件中添加apiGateway选项,但我总是遇到CORS问题(即经典的No 'access-control-allow-origin' header is present)。我已经尝试了来自客户端/请求端的标头和来自服务器端的响应的每种组合(请参见下面的代码)。

  2. 或者,我无法使用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);
    });

iCMS 回答:Serverless,Bref PHP和Slim的二进制响应得到CORS或base64编码

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/1934422.html

大家都在问