Sharepoint Rest API php curl post 与 docx 文件问题
Sharepoint Rest API php curl post with docx file issue
有与此类似的问题,但我没有发现任何与我的问题直接相关的问题。我对 PHP 和 curl 有点陌生,所以请多多包涵并提前致谢。
说明:
我有一个 php 应用程序正在将文件上传到 Sharepoint 2019 rest api。到目前为止,它适用于所有文件类型,但 .doc 和 .docx 格式文件除外。这些文件已成功发布,但一旦下载并打开,我就会收到如下错误:
“Word 在 {filename}.docx 中发现不可读的内容”。您要恢复此文档的内容吗?如果您信任此文档的来源,请单击“是”。
如果我单击“是”,文件将毫无问题地打开。如果我直接从 Sharepoint 站点下载文件,也会出现同样的问题。如何使用 curl 将 docx 文件传递给 rest api?似乎存在一些编码问题,但我不确定如何判断它在哪一边,因为 Sharepoint 告诉我的上传没有任何问题。我在 stack overflow 上发现的另一篇文章将数据分开,但那是 docusign rest api 并且是从 2013 年开始的。发现 Here。我是否也需要分解通话数据?
下面是我的文件上传代码
$files = $_FILES;
$local_file = $_FILES['input_document_upload'];
$fileName = $local_file['name'];
//I am assuming there is something with the encoding for curl_file_create below I am missing
$data = array(
'uploaded_file' => curl_file_create($local_file['tmp_name'], $local_file['type'], $fileName)
);
$client_upload_url = //ends in _api/web/lists/getbytitle('{documentFolder}')/rootfolder/files/add
$client_upload_url .= "(url='". $fileName ."',overwrite=true)";
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $client_upload_url,//<-- no problem here since it uploads correctly 99% of the time
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_NONE ,
CURLOPT_POSTFIELDS=> $data,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => array(
"Accept: application/json;odata=verbose",
"cache-control: no-cache",
"X-RequestDigest: " . $digest_value,
//hardcoded the below type, but I have used several different content-type settings to try to get this working
//multipart/form-data
//application/octet-stream
"Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"Authorization: //redacted
),
));
$response = curl_exec($curl);
感谢您抽出宝贵时间!
经过大量实验和搜索,我找到了这个问题的答案。最大的罪魁祸首确实是内容类型。如果您使用以下代码:
$data = array(
'uploaded_file' => curl_file_create($local_file['tmp_name'], $local_file['type'], $fileName)
);
/// redacted for space
CURLOPT_POSTFIELDS=> $data,
curl 将自动删除您提供的任何 content-type 并提供自己的。你得到以下 headers:
Content-Type: multipart/form-data; boundary=----------637571310612295910
Content-Length: 12184
------------637571310612295910
Content-Disposition: form-data; name="uploaded_file"; filename="{filename}.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Sharepoint 根本不喜欢这样。所以,你需要发送二进制数据,而不是 multipart/form-data。这可以像这样实现:
$uploadFile = file_get_contents($local_file['tmp_name']);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $client_upload_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_NONE ,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS=> $uploadFile, //<-- where the magic happens
CURLOPT_HTTPHEADER => array(
"Accept: application/json;odata=verbose",
"cache-control: no-cache",
"X-RequestDigest: " . $digest_value,
"Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document",//
"Authorization: {values}
),
));
这将为您带来如下结果
Accept: application/json; odata=verbose
Cache-Control: no-cache
X-RequestDigest:{redacted}
Authorization: {redacted}
Connection: Keep-Alive
Request-Id: |1bf3eca4-45702011fc30c20b.2.
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Content-Length: 11947
{raw body here, not multipart/formdata}
这个故事的寓意是 file_get_contents 将为您提供字符串形式的二进制数据。您可以直接将其转储到 CURLOPT_POSTFIELDS.
这件事的灵感来自于 2008 年 post found here
有与此类似的问题,但我没有发现任何与我的问题直接相关的问题。我对 PHP 和 curl 有点陌生,所以请多多包涵并提前致谢。
说明: 我有一个 php 应用程序正在将文件上传到 Sharepoint 2019 rest api。到目前为止,它适用于所有文件类型,但 .doc 和 .docx 格式文件除外。这些文件已成功发布,但一旦下载并打开,我就会收到如下错误:
“Word 在 {filename}.docx 中发现不可读的内容”。您要恢复此文档的内容吗?如果您信任此文档的来源,请单击“是”。
如果我单击“是”,文件将毫无问题地打开。如果我直接从 Sharepoint 站点下载文件,也会出现同样的问题。如何使用 curl 将 docx 文件传递给 rest api?似乎存在一些编码问题,但我不确定如何判断它在哪一边,因为 Sharepoint 告诉我的上传没有任何问题。我在 stack overflow 上发现的另一篇文章将数据分开,但那是 docusign rest api 并且是从 2013 年开始的。发现 Here。我是否也需要分解通话数据?
下面是我的文件上传代码
$files = $_FILES;
$local_file = $_FILES['input_document_upload'];
$fileName = $local_file['name'];
//I am assuming there is something with the encoding for curl_file_create below I am missing
$data = array(
'uploaded_file' => curl_file_create($local_file['tmp_name'], $local_file['type'], $fileName)
);
$client_upload_url = //ends in _api/web/lists/getbytitle('{documentFolder}')/rootfolder/files/add
$client_upload_url .= "(url='". $fileName ."',overwrite=true)";
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $client_upload_url,//<-- no problem here since it uploads correctly 99% of the time
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_NONE ,
CURLOPT_POSTFIELDS=> $data,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => array(
"Accept: application/json;odata=verbose",
"cache-control: no-cache",
"X-RequestDigest: " . $digest_value,
//hardcoded the below type, but I have used several different content-type settings to try to get this working
//multipart/form-data
//application/octet-stream
"Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"Authorization: //redacted
),
));
$response = curl_exec($curl);
感谢您抽出宝贵时间!
经过大量实验和搜索,我找到了这个问题的答案。最大的罪魁祸首确实是内容类型。如果您使用以下代码:
$data = array(
'uploaded_file' => curl_file_create($local_file['tmp_name'], $local_file['type'], $fileName)
);
/// redacted for space
CURLOPT_POSTFIELDS=> $data,
curl 将自动删除您提供的任何 content-type 并提供自己的。你得到以下 headers:
Content-Type: multipart/form-data; boundary=----------637571310612295910
Content-Length: 12184
------------637571310612295910
Content-Disposition: form-data; name="uploaded_file"; filename="{filename}.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Sharepoint 根本不喜欢这样。所以,你需要发送二进制数据,而不是 multipart/form-data。这可以像这样实现:
$uploadFile = file_get_contents($local_file['tmp_name']);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $client_upload_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_NONE ,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS=> $uploadFile, //<-- where the magic happens
CURLOPT_HTTPHEADER => array(
"Accept: application/json;odata=verbose",
"cache-control: no-cache",
"X-RequestDigest: " . $digest_value,
"Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document",//
"Authorization: {values}
),
));
这将为您带来如下结果
Accept: application/json; odata=verbose
Cache-Control: no-cache
X-RequestDigest:{redacted}
Authorization: {redacted}
Connection: Keep-Alive
Request-Id: |1bf3eca4-45702011fc30c20b.2.
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Content-Length: 11947
{raw body here, not multipart/formdata}
这个故事的寓意是 file_get_contents 将为您提供字符串形式的二进制数据。您可以直接将其转储到 CURLOPT_POSTFIELDS.
这件事的灵感来自于 2008 年 post found here