我正在为我的公司编写一系列 Powershell 脚本,用于在 Box.com 之间传输数据。我无法弄清楚的一件事是上传文件。Box API 需要进行多部分 POST 操作才能上传,我在这里看到了一些答案,表明我应该能够在 Powershell 中执行此操作(例如 这个)。但我似乎无法让它发挥作用。

这是我现在的代码:

Function Post-File {
    Param(
            [Parameter(Mandatory=$True,Position=1)]
            [string]$SourcePath,
            [Parameter(Mandatory=$False,Position=2)]            
            [string]$FolderId = ############
    )

    #Variables for building URIs
    $baseUrl = "https://upload.box.com/api/2.0/files/content"

    #Set Authorization for API requests
    $headers = @{}
    $AccessToken = Refresh-Tokens #A reference to another function that definitely works
    $headers.Add("Authorization", "Bearer $AccessToken")

    #Set POST content
    $body = @{}
    $body.Add("filename",  [IO.File]::ReadAllBytes($SourcePath))
    $body.Add("parent_id", $FolderId)

    #Upload the file
    Invoke-RestMethod -Uri $baseUrl -Method Post -Headers $headers -ContentType "multipart/form-data" -Body $body
}

这是我得到的回复:

{
 "type":"error",
 "status":400,
 "code":"invalid_request_parameters",
 "help_url":"http://developers.box.com/docs/#errors",
 "message":"Invalid input parameters in request",
 "request_id":"1764475572534bcddfe04b7"
}

我还尝试了其他一些不起作用的排列。我尝试过使用 -InFile 切换到 Invoke-RestMethod 代替 -Body. 。我也尝试过使用 Get-Content -Raw 代替 [IO.File]::ReadAllBytes. 。这两个都会返回一个更通用的错误: The server encountered an internal error or misconfiguration and was unable to complete your request..

我很确定这与我的 filename 参数不正确,但我不知道如何修复它。根据 盒子API, ,这就是curl 中的样子。有人可以帮我正确地将其翻译为 Powershell 吗?

https://upload.box.com/api/2.0/files/content \
-H "Authorization: Bearer ACCESS_TOKEN" \
-F filename=@FILE_NAME \
-F parent_id=PARENT_FOLDER_ID
有帮助吗?

解决方案

在 PowerShell 中,有几件事使得这有点棘手:

  1. filename 参数指定文件的名称,而不是内容。
  2. 需要请求正文才能指定文件名和目标。
  3. PowerShell 对待 -InFile-Body 论据是相互排斥的。
  4. PowerShell 似乎本身不支持 multipart/form-data 帖子,根据 问题 你提到的。

由于请求正文是必需的 (1,2)——因此 -InFile 无法使用(3)——我想你可能需要自己动手 multipart/form-data body (4) 包含必要的元数据和文件内容。 这篇博文 描述了这样做的方法。内容是一个短字符串(一条推文),但原理是相同的。

下面是我刚刚使用 Box Windows SDK 执行的上传的 Fiddler 跟踪。这显示了请求通过网络时的外观。这 $BOUNDARY 是一个任意的、唯一的字符串——GUID 效果很好。

POST https://upload.box.com/api/2.0/files/content HTTP/1.1
Authorization: Bearer $TOKEN
Content-Type: multipart/form-data; boundary="$BOUNDARY"
Host: upload.box.com
Content-Length: 2118
Accept-Encoding: gzip, deflate

--$BOUNDARY

Content-Disposition: form-data; name="file"; filename="$FILENAME"

<THE CONTENT OF $FILENAME>    

--$BOUNDARY

Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name="metadata"

{"parent":{"id":"$PARENT_FOLDER_ID"},"name":"$FILENAME"}

--$BOUNDARY--

这是我收到的回复:

HTTP/1.1 201 Created
Date: Mon, 14 Apr 2014 12:52:33 GMT
Server: Apache
Cache-Control: no-cache, no-store
Content-Length: 364
Connection: close
Content-Type: application/json

{"total_count":1,"entries":[{"type":"file","id":"$ID","name":"$FILENAME", ... }]}

其他提示

我可能听起来很愚蠢,但是当你这样做时会发生什么?

$body.Add("filename",  $([IO.File]::ReadAllBytes($SourcePath)))
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top