PHP/Curl上传文件至SharePoint失败:返回跳转但文件未找到
问题描述
使用以下PHP代码尝试将本地HTML文件上传至SharePoint:
$the_file = file_get_contents("".realpath(dirname(__FILE__))."/<file_name>.htm");//Note: the file already exists in the dir $ch = curl_init(); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_VERBOSE, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data")); curl_setopt($ch, CURLOPT_USERPWD, "<usr>:<pass>"); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Linux i686; rv:6.0) Gecko/20100101 Firefox/6.0Mozilla/4.0 (compatible;)"); curl_setopt($ch, CURLOPT_URL, "https://<xxxx>.sharepoint.com/sites/<xxx>/Shared%20Documents/Forms/AllItems.aspx"); curl_setopt($ch, CURLOPT_POST, true); $post = array('file_contents' => "the_file"); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); $response = curl_exec($ch); if(curl_errno($ch)) { echo json_encode('Error: ' . curl_error($ch)); } else { echo ($response); } curl_close($ch);
执行后返回重定向响应:
<html><head><title>Object moved</title></head><body> <h2>Object moved to <a href="https://<xxxx>.sharepoint.com/sites/<xxxx>/_layouts/15/Authenticate.aspx?Source=%2Fsites%2F<xxx>%2FShared%20Documents%2FForms%2FAllItems%2Easpx">here</a>.</h2> </body></html>
且SharePoint对应位置未找到上传文件。
核心错误点
- 目标URL错误:你请求的
AllItems.aspx是文档库的前端浏览页面,不是文件上传的接口,SharePoint不支持通过该页面POST上传文件。 - 认证方式失效:现代SharePoint Online已不再支持简单的用户名密码Basic认证,直接用
CURLOPT_USERPWD会触发重定向到认证页面,导致上传请求未被授权。 - POST数据错误:代码中
'file_contents' => "the_file"是字符串而非变量$the_file,实际没有传递文件内容;且手动设置Content-type: multipart/form-data会干扰curl自动生成正确的请求边界,导致上传格式无效。
修复方案
方案1:使用SharePoint REST API上传(推荐)
REST API是SharePoint官方推荐的文件操作方式,需要先获取有效的OAuth 2.0访问令牌(可通过Azure AD应用注册获取)。以下是简化示例:
$siteUrl = "https://<xxxx>.sharepoint.com/sites/<xxx>"; $folderPath = "/Shared Documents"; $fileName = "<file_name>.htm"; $fileContent = file_get_contents(realpath(dirname(__FILE__)) . "/$fileName"); $uploadUrl = "$siteUrl/_api/web/getfolderbyserverrelativeurl('$folderPath')/files/add(overwrite=true,url='$fileName')"; $ch = curl_init($uploadUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer YOUR_ACCESS_TOKEN", "Content-Type: text/html", "Content-Length: " . strlen($fileContent) ]); curl_setopt($ch, CURLOPT_POSTFIELDS, $fileContent); $response = curl_exec($ch); if(curl_errno($ch)) { echo "Error: " . curl_error($ch); } else { echo "上传成功"; } curl_close($ch);
方案2:使用WebDAV协议上传
若环境支持,可通过WebDAV的PUT请求直接上传文件,需使用支持现代认证的方式(如App密码或OAuth令牌):
$filePath = realpath(dirname(__FILE__)) . "/<file_name>.htm"; $remoteUrl = "https://<xxxx>.sharepoint.com/sites/<xxx>/Shared%20Documents/<file_name>.htm"; $ch = curl_init($remoteUrl); curl_setopt($ch, CURLOPT_PUT, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 若使用App密码,可保留CURLOPT_USERPWD;否则替换为Bearer令牌 curl_setopt($ch, CURLOPT_USERPWD, "<usr>:<app_password>"); curl_setopt($ch, CURLOPT_INFILE, fopen($filePath, 'r')); curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath)); $response = curl_exec($ch); if(curl_errno($ch)) { echo "Error: " . curl_error($ch); } else { echo "上传成功"; } curl_close($ch);
关键注意事项
- 现代SharePoint Online必须使用OAuth 2.0认证,需在Azure AD中注册应用并配置相应权限;经典站点可临时启用App密码,但不推荐长期使用。
- 所有文件操作应使用官方提供的API或标准协议(REST、WebDAV、Graph API),避免直接调用前端页面URL。
内容的提问来源于stack exchange,提问作者andreas
相关产品推荐
相关产品推荐

