1

我构建了一个自定义的 Wordpress 插件。插件前端是一个 Facebook React JS 应用程序,它通过简码嵌入到 Wordpress 页面中。它专门使用 Wordpress REST API 在客户端浏览器和 Wordpress 之间发送和检索 JSON。在这种情况下,Wordpress 充当了中间人。处理客户端请求的 REST 路由只需调用后端 REST API 并将响应从其他服务器返回给客户端。

我刚刚向应用程序添加了一项新功能,允许用户下载由不同后端服务器(不是 Wordpress)动态生成的 PDF 文件。我的计划是在 Wordpress REST API 上添加另一个路由,该路由将调用后端服务器并返回由其他服务器生成的 PDF 文件。Wordpress 基本上只是将请求代理到后端服务器并将响应返回给客户端浏览器。

但是,当我尝试这样做时,响应正文是一个字符串,而不是从后端服务器返回的原始字节数组。我可以直接向后端服务器发出请求,它会正确返回 PDF 文件(例如http://default-internal-backend-server.example.com/api/v1/quote/asdf123/pdf)。

让 Wordpress 插件处理 REST 请求(例如https://example.com/wp-json/my-plugin/v1/quote/asdf123/pdf)并从上游服务器返回原始、未触及的响应的正确方法是什么?

例如,我正在这样做:

在应用程序的 UI 上,我有一个简单的锚标记,如下所示:

<a href="http://example.com/wp-json/my-plugin/quote/asdf123/pdf" download="quote.pdf">
   <span>Download PDF</span>
</a>

上面的 URL 在插件的 REST Routes 中注册如下:

class My_Plugin_REST_Controller extends WP_REST_Controller {
    // ****

    register_rest_route( 'my-plugin', '/quote/(?P<id>\w+)/pdf',
        array(
            array(
                'methods' => WP_REST_Server::READABLE,
                'callback' => array( $this, 'get_quote_pdf' ),
                    'args' => array()
            )
        )
    );

    public function get_quote_pdf( $request ) {
        $api_service = API_Service::get_instance();
        $response = $api_service->getQuotePdf( $request );
        $http_response = new WP_REST_Response( $response, 200 );
        $http_response->header('Content-Type', 'application/pdf');
        return $http_response;
    }

    // ****
}

class API_Service {
    public function getQuotePdf( $request ) {
        $curl = curl_init();

        $default_options = array(
            'url' => 'http://default-internal-backend-server.example.com'
        );

        $api_options = get_option( 'my_plugin_api', $default_options );

        $api_url = $api_options['url'] . '/api/v1/quote/' . $request['id'] . '/pdf'

        curl_setopt_array($curl, array(
            CURLOPT_URL             => $api_url,
            CURLOPT_RETURNTRANSFER  => true,
            CURLOPT_ENCODING        => '',
            CURLOPT_MAXREDIRS       => 10,
            CURLOPT_TIMEOUT         => 30,
            CURLOPT_HTTP_VERSION    => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST   => "GET",
            CURLOPT_HTTPHEADER      => array(
                "Accept: application/pdf",
                "Cache-Control: no-cache"
            )
        ));

        $response = curl_exec( $curl );
        $err = curl_error( $curl );

        curl_close( $curl );

        if ( $err ) {
            return null;
        } else {
            return $response;
        }
    }
}

Wordpress 正在正确处理来自客户端 JavaScript 应用程序的请求,正在正确调用后端服务器,后端服务器正在返回 PDF 文件。

但是,对于上面的示例,Wordpress 返回 PDF 的字符串表示形式,而不是外部服务器返回的原始字节。我不得不与 the 斗争以WP_Rest_Response使其也设置Content-Typeappplication/pdf。如果我设置Content-Length标题,它将无缘无故地更改为Content-Typeapplication/json

如何返回原始字节而不是响应的字符串版本?

我的下一步是完全删除与此相关的 Wordpress,并链接到浏览器中使用反向代理访问的不同 URL(例如https://my.example.com/quote/asdf123/pdf )直接内部服务器。

我确实读到 PHP 没有原生数据类型 byte[],这可能是限制因素。

4

0 回答 0