itsource

파일을 다운로드하기 위한 WP_REST_Response

mycopycode 2023. 3. 8. 21:10
반응형

파일을 다운로드하기 위한 WP_REST_Response

문서(생성된 PDF, CSV)를 반환할 수 있습니까?WP_REST_ResponseWordPress에서요?

지금까지 다음을 사용하여 커스텀엔드포인트를 등록하고 있습니다.register_rest_resource그러나 파일을 반환하려고 하면(예를 들어 PHP 사용)fpassthru($f)또는readfile($f)"Headers already sent" (헤더 이미 전송 완료) 오류가 나타난다.

다른 말로 하자면 Wordpress REST API를 사용하여 파일을 반환하는 방법?

어떤 도움이라도 감사합니다!

감사해요.

기본적으로는 모든 REST 응답이 통과됩니다.json_encode()JSON 문자열을 반환합니다.그러나 REST 서버는 바이너리 데이터를 반환하는 데 사용할 수 있는 WP 훅을 제공합니다.

코드 샘플:

<?php
/**
 * Serves an image via the REST endpoint.
 *
 * By default, every REST response is passed through json_encode(), as the
 * typical REST response contains JSON data.
 *
 * This method hooks into the REST server to return a binary image.
 *
 * @param string $path Absolute path to the image to serve.
 * @param string $type The image mime type [png|jpg|gif]. Default is 'png'.
 *
 * @return WP_REST_Response The REST response object to serve an image.
 */
function my_serve_image( $path, $type = 'png' ) {
    $response = new WP_REST_Response;

    if ( file_exists( $path ) ) {
        // Image exists, prepare a binary-data response.
        $response->set_data( file_get_contents( $path ) );
        $response->set_headers( [
            'Content-Type'   => "image/$type",
            'Content-Length' => filesize( $path ),
        ] );

        // HERE → This filter will return our binary image!
        add_filter( 'rest_pre_serve_request', 'my_do_serve_image', 0, 2 );
    } else {
        // Return a simple "not-found" JSON response.
        $response->set_data( 'not-found' );
        $response->set_status( 404 );
    }

    return $response;
}

/**
 * Action handler that is used by `serve_image()` to serve a binary image
 * instead of a JSON string.
 *
 * @return bool Returns true, if the image was served; this will skip the
 *              default REST response logic.
 */
function my_do_serve_image( $served, $result ) {
    $is_image   = false;
    $image_data = null;

    // Check the "Content-Type" header to confirm that we really want to return
    // binary image data.
    foreach ( $result->get_headers() as $header => $value ) {
        if ( 'content-type' === strtolower( $header ) ) {
            $is_image   = 0 === strpos( $value, 'image/' );
            $image_data = $result->get_data();
            break;
        }
    }

    // Output the binary data and tell the REST server to not send any other
    // details (via "return true").
    if ( $is_image && is_string( $image_data ) ) {
        echo $image_data;

        return true;
    }

    return $served;
}

사용 예:

<?php
// Register the REST endpoint.
register_rest_route( 'my_sample/v1', 'image', [
    'method' => 'GET',
    'callback' => 'my_rest_get_image'
] );

// Return the image data using our function above.
function my_rest_get_image() {
    return my_serve_image( 'path/to/image.jpeg', 'jpg' );
}

(나 자신도 빨리 이것이 필요하기 때문에 불완전한 답변을 작성해야 합니다.)

WP Media에 확인 중.../?rest_route=/wp/v2/media/ID a JSON API요청된 미디어 파일 링크가 있는 응답입니다.

예를 들어 이미지 1의 경우source _url포함하다.../wp-content/uploads/2021/06/Screenshot-2021-06-18-at-10.25.05-150x150.png.

코멘트에 이어(스트림 바이너리가 아닌 링크) 파일을 WP Media 컬렉션에 추가합니다.그렇지 않으면 커스텀엔드포인트는 생성된 AND 저장 파일에 링크된 유사한 응답으로 응답할 수 있습니다.

그러면 JSON API 호환 클라이언트가 필요한 작업을 수행할 수 있습니다.이 경우 다운로드 링크를 생성합니다.

사용할 수 없습니다.WP_REST_Response이 일을 하기 위해서.그러나 나머지 API를 사용하여 다른 것을 반환할 수도 있습니다.

완전한 응답 준비가 완료되었다고 확신하는 경우(헤더 포함)Content-Disposition다운로드의 경우)는, 간단하게 할 수 있습니다.exit;최종 응답을 생성한 후.이 경우 나중에 호출될 수 있는 후크는 완전히 무시되므로 주의하여 사용하십시오.

의 예.csv

$filename = 'example-file.csv';
header("Access-Control-Expose-Headers: Content-Disposition", false);
header('Content-type: text/csv');
header("Content-Disposition: attachment; filename=\"$filename\"");

// output starts here, do not add headers from this point on.
$csv_file = fopen('php://output', 'w');

$csv_header = array(
    'column-1',
    'column-2',
    'column-3',
);

fputcsv($csv_file, $csv_header);

$data = array(
    array('a1', 'b1', 'c1'),
    array('a2', 'b2', 'c2'),
    array('a3', 'b3', 'c3'),
);

foreach ($data as $csv_data_entry) {
    fputcsv($csv_file, $csv_data_entry);
}

fclose($csv_file);

// With a non-file request, you would usually return the result.
// In this case, this would cause the "Headers already sent" errors, so an exit is required.
exit;

언급URL : https://stackoverflow.com/questions/44524071/wp-rest-response-to-download-a-file

반응형