php - 带有 docx 文件问题的 Sharepoint Rest API php curl 帖子
问题描述
有类似的问题,但我没有发现任何与我的问题直接相关的内容。我对 PHP 和 curl 有点陌生,所以请多多包涵,并提前致谢。
描述:我有一个将文件上传到 Sharepoint 2019 rest api 的 php 应用程序。到目前为止,它适用于所有文件类型,除了 .doc 和 .docx 格式的文件。这些文件已成功发布,但一旦下载并打开,我会收到以下错误:
“Word 在 {filename}.docx 中发现了不可读的内容”。是否要恢复此文档的内容?如果您信任此文档的来源,请单击是。”
如果单击“是”,则文件将毫无问题地打开。如果我直接从 Sharepoint 站点下载文件,也会出现同样的问题。如何使用 curl 将 docx 文件传递给 rest api?似乎存在一些编码问题,但我不确定如何判断它在哪一侧,因为它告诉我的上传没有任何问题。我在堆栈溢出中发现的另一篇文章将数据分开,但那是针对 docusign rest api 的,来自 2013 年。在此处找到。我是否也需要分解通话数据?
以下是我的文件上传代码
$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: 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 年的一篇文章,发现于此处
推荐阅读
- javascript - 在一个 html 表格单元格中分层多个图像
- python - 如何使用python获取当前迭代循环列表的行
- mysql - 跳过第一条重复记录并更新其他记录
- r - 是否可以在 Sweave 中给图形/绘图标签?
- java - 必须首先在孩子的父母上调用 removeView()
- javascript - 使用 Electron.js 加载 Nunjucks 模板
- text - 你能说出这个文本编辑器的名字吗?
- php - 仅获取当前微秒
- java - RxTextView.textChanges 与 Edittext 上的 setText
- spring-integration - “isConnected()”控制总线命令spring集成