DropBox API 应用程序/八位字节流标头

Posted

技术标签:

【中文标题】DropBox API 应用程序/八位字节流标头【英文标题】:DropBox API application/octet-stream header 【发布时间】:2017-10-21 12:16:03 【问题描述】:

我正在尝试使用 php 向 Dropbox API 发出 cUrl 请求,以便开始上传一个非常大的 zip 文件。这是我正在尝试实施的文档,位于https://www.dropbox.com/developers/documentation/http/documentation#files-upload -

网址结构:https://content.dropboxapi.com/2/files/upload_session/start

示例 cUrl 请求:

curl -X POST https://content.dropboxapi.com/2/files/upload_session/start \
    --header "Authorization: Bearer <get access token>" \
    --header "Dropbox-API-Arg: \"close\": false" \
    --header "Content-Type: application/octet-stream" \
    --data-binary @local_file.txt

这是我的代码:

$uploads = wp_upload_dir();
$file = $uploads['basedir']."/maintainme/backups/files/backup_".$filename.'/'.$filename.'.zip';
$ch = curl_init();
$url = 'https://content.dropboxapi.com/2/files/upload_session/start';
$headers = array(
    'Authorization: Bearer ' .$dropbox_token,
    'Dropbox-API-Arg: \"close\": false',
    'Content-Type: application/octet-stream',
);
$fields = array('file' => '@' . $file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields ); 
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$result = curl_exec($ch);
curl_close($ch);

我得到的错误信息是:

调用 API 函数“files/upload_session/start”时出错:HTTP“Content-Type”标头错误:“application/octet-stream;boundary=--------------- ---------1ee7d00b0e9b0c47"。期待“application/octet-stream”、“text/plain; charset=dropbox-cors-hack”之一。

似乎每次我尝试发出此请求时,此 'Boundary=------------blahblahblah' 都会附加到我的内容类型标头中。谁有想法???谢谢!

【问题讨论】:

【参考方案1】:

解决了!一时兴起,我检查了http://php.net/manual/en/function.curl-setopt.php 上的“CURLOPT_POSTFIELDS”选项,它是这样说的:

要在 HTTP“POST”操作中发布的完整数据。要发布文件,请在文件名前加上 @ 并使用完整路径。可以通过使用格式为“;type=mimetype”的文件名来明确指定文件类型。此参数可以作为 urlencoded 字符串(如 'para1=val1&para2=val2&...')或作为字段名称作为键和字段数据作为值的数组传递。 如果 value 是一个数组,则 Content-Type 标头将设置为 multipart/form-data。从 PHP 5.2.0 开始,如果文件以 @ 前缀传递给此选项,则 value 必须是数组。自 PHP 5.5.0 起,@ 前缀已弃用,可以使用 CURLFile 发送文件。通过将 CURLOPT_SAFE_UPLOAD 选项设置为 TRUE,可以禁用 @ 前缀以安全传递以 @ 开头的值。

以上段落中的相关部分以粗体显示。显然,将数组传递给 CURLOPT_POSTFIELDS 选项是在 Content-Type 中附加 'Boundary=----blahblahblah' 并导致 API 调用失败。我变了

curl_setopt($ch, CURLOPT_POSTFIELDS, $fields );

curl_setopt($ch, CURLOPT_POSTFIELDS, '@'.$file );

然后再试一次。最初的问题已修复,但随后我在这部分代码中遇到了“Dropbox-API-Arg”行的新问题:

$headers = array(
    'Authorization: Bearer ' .$dropbox_token,
    'Dropbox-API-Arg: \"close\": false',
    'Content-Type: application/octet-stream',
);

事实证明,这些参数需要正确地进行 JSON 编码。我用下面的代码做到了这一点:

$args = array('close'=>false);
$args = json_encode($args);

然后变了

'Dropbox-API-Arg: \"close\": false' 

到:

'Dropbox-API-Arg:'.$args

这是完整的最终代码:

    $uploads = wp_upload_dir();
    $file = $uploads['basedir']."/maintainme/backups/files/backup_".$filename.'/'.$filename.'.zip';
    error_log($file);

    $args = array('close'=>false);
    $args = json_encode($args);

    $ch = curl_init();
    $url = 'https://content.dropboxapi.com/2/files/upload_session/start';
    $headers = array(
        'Authorization: Bearer ' .$dropbox_token,
        'Dropbox-API-Arg:'.$args,
        'Content-Type: application/octet-stream',
    );
    $fields = array('file' => '@' . $file);
    error_log($fields);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, '@'.$file ); 
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    $result = curl_exec($ch);
    error_log($result);
    curl_close($ch);

【讨论】:

对于那些稍后提出这个问题的人 - 我在将文件从表单元素传递到 Dropbox API 时遇到问题,我发现 this link 帮助我了解我需要打开我的本地服务器临时文件使用$path = $_FILES["fileToUpload"]["tmp_name"];(来自关于$_FILES的PHP文档)和$fp = fopen($path, 'rb');并在CURLOPT_INFILE中使用$fpcurl_setopt($ch, CURLOPT_INFILE, $fp);

以上是关于DropBox API 应用程序/八位字节流标头的主要内容,如果未能解决你的问题,请参考以下文章

Webapp2 请求应用程序/八位字节流文件上传

XLSX 客户端从后端 api 响应中保存:二进制字符串、应用程序/八位字节流

未找到媒体类型 = 应用程序/八位字节流的 MessageBodyReader

无法将应用程序/八位字节流解析为节点 js 中的图像

Spring Android POST在ResponseEntity中没有返回类型应用程序/八位字节流

文件上传错误“应用程序/八位字节流”