Access VBA上传JPG至自建服务器报错(PHP错误码3)求帮助
Access VBA上传JPG到Web服务器失败(PHP错误码3)
问题描述
用户编写Access VBA代码上传JPG文件至自建Web服务器,服务器端PHP返回$_FILES错误码3(文件仅部分上传),具体返回信息如下:
Array ( [fileToUpload] => Array ( [name] => testimage.jpg [full_path] => testimage.jpg [type] => [tmp_name] => [error] => 3 [size] => 0 ) )
用户的VBA代码:
Sub UploadJPGWithCURL() Dim winHttpReq As Object Dim fileData As String Dim boundary As String Dim fileName As String Dim filePath As String filePath = "Z:\Desktop\testimage.jpg" fileName = "testimage.jpg" boundary = "----------------------------" & Format(Now, "ddmmyyyyhhmmss") fileData = "--" & boundary & vbCrLf fileData = fileData & "Content-Disposition: form-data; name=""fileToUpload""; filename=""" & fileName & """" & vbCrLf fileData = fileData & "Content-Type: image/jpeg" & vbCrLf & vbCrLf 'fileData = fileData & filePath & vbCrLf fileData = fileData & getBinaryFile(filePath) & vbCrLf fileData = fileData & "--" & boundary & "--" & vbCrLf Debug.Print fileData Set winHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1") winHttpReq.Open "POST", "[THE URL TO MY WEBSERVER PHP PAGE THAT IS GOING TO PROCESS THE UPLOAD]", False winHttpReq.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & boundary winHttpReq.send (fileData) If winHttpReq.Status = 200 Then Debug.Print winHttpReq.ResponseText Else Debug.Print "Request failed with status code: " & winHttpReq.Status End If End Sub Function getBinaryFile(filePath) Dim binaryStream Set binaryStream = CreateObject("ADODB.Stream") binaryStream.Type = 1 binaryStream.Open binaryStream.LoadFromFile filePath getBinaryFile = binaryStream.Read binaryStream.Close End Function
错误原因分析
- 二进制数据转字符串丢失:VBA的
String是Unicode编码,无法正确存储二进制字节(如JPG中的非ASCII字节),直接将二进制文件内容赋值给fileData会导致数据损坏。 - 请求体拼接方式错误:用字符串拼接边界、头部和二进制内容,会破坏二进制流的完整性,导致服务器无法识别完整文件。
- Send方法参数类型错误:WinHttpRequest的
send方法传入字符串时会按文本发送,而二进制文件需要以字节流形式传输。
修正后的代码
核心修改
- 用ADODB.Stream构建完整的二进制请求体,避免字符串转换丢失数据
- 所有边界、头部信息和文件内容均以二进制方式写入流
- 直接发送二进制流而非字符串
Sub UploadJPGWithWinHttp() Dim winHttpReq As Object Dim requestStream As Object Dim boundary As String Dim fileName As String Dim filePath As String filePath = "Z:\Desktop\testimage.jpg" fileName = "testimage.jpg" boundary = "----------------------------" & Format(Now, "ddmmyyyyhhmmss") ' 创建二进制请求流 Set requestStream = CreateObject("ADODB.Stream") requestStream.Type = 1 ' 二进制类型 requestStream.Open ' 写入边界和表单头部(转二进制) WriteBinaryString requestStream, "--" & boundary & vbCrLf WriteBinaryString requestStream, "Content-Disposition: form-data; name=""fileToUpload""; filename=""" & fileName & """" & vbCrLf WriteBinaryString requestStream, "Content-Type: image/jpeg" & vbCrLf & vbCrLf ' 写入文件二进制内容 Dim fileStream As Object Set fileStream = CreateObject("ADODB.Stream") fileStream.Type = 1 fileStream.Open fileStream.LoadFromFile filePath fileStream.CopyTo requestStream fileStream.Close Set fileStream = Nothing ' 写入结束边界 WriteBinaryString requestStream, vbCrLf & "--" & boundary & "--" & vbCrLf ' 初始化并发送请求 Set winHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1") winHttpReq.Open "POST", "[你的服务器PHP处理页面URL]", False winHttpReq.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & boundary requestStream.Position = 0 ' 重置流指针到开头 winHttpReq.send requestStream ' 处理响应 If winHttpReq.Status = 200 Then Debug.Print winHttpReq.ResponseText Else Debug.Print "请求失败,状态码: " & winHttpReq.Status End If ' 清理资源 requestStream.Close Set requestStream = Nothing Set winHttpReq = Nothing End Sub ' 辅助函数:将字符串转为二进制并写入流 Sub WriteBinaryString(stream As Object, text As String) Dim textStream As Object Set textStream = CreateObject("ADODB.Stream") textStream.Type = 2 ' 文本类型 textStream.Charset = "utf-8" textStream.Open textStream.WriteText text textStream.Position = 0 textStream.Type = 1 ' 转为二进制 textStream.CopyTo stream textStream.Close Set textStream = Nothing End Sub
额外检查项
- 确认服务器PHP配置中
upload_max_filesize和post_max_size值足够大,避免文件大小限制导致部分上传 - 检查服务器临时目录(
upload_tmp_dir)是否有读写权限 - 确保本地文件路径正确,且文件未被其他程序占用
内容的提问来源于stack exchange,提问作者Chris Lydon
相关产品推荐
相关产品推荐

