使用 MultipartEntity 上傳圖片,無報錯但服務端未收到文件。PHP 端 move_uploaded_file 未生效。
// Linux 服務器
ls -ld /tmp # 檢查臨時目錄權限,需 www-data 可寫
ls -ld /var/www/uploads # 目標目錄權限,需 www-data 可寫
// PHP 腳本中檢查
$tmpFile = $_FILES['uploaded']['tmp_name'];
$destFile = '/var/www/uploads/' . $_FILES['uploaded']['name'];
if (is_uploaded_file($tmpFile)) {
if (move_uploaded_file($tmpFile, $destFile)) {
echo "success";
} else {
error_log("move_uploaded_file failed: " . error_get_last()['message']);
// 通常是目標目錄無寫權限
}
} else {
error_log("No uploaded file in tmp: " . $tmpFile);
}
// 關鍵:設置正確的 Content-Type,避免瀏覽器兼容模式導致邊界解析失敗
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.STRICT); // 推薦 STRICT
// 文件部分:明確指定 MIME 類型
FileBody fileBody = new FileBody(new File(path), "image/png", "UTF-8"); // 或 ContentType.create("image/png")
entity.addPart("uploaded", fileBody); // 名稱需與 PHP $_FILES['uploaded'] 一致
// 可選:添加其他字段
entity.addPart("userId", new StringBody(userId, ContentType.TEXT_PLAIN));
// 設置請求實體
HttpPost post = new HttpPost(url);
post.setEntity(entity);
// 執行並檢查響應
HttpResponse response = client.execute(post);
int status = response.getStatusLine().getStatusCode();
String respBody = EntityUtils.toString(response.getEntity());
Log.d("Upload", "Status: " + status + ", Response: " + respBody);
false, 'message' => ''];
if (!isset($_FILES['uploaded']) || $_FILES['uploaded']['error'] !== UPLOAD_ERR_OK) {
$response['message'] = 'Upload error: ' . ($_FILES['uploaded']['error'] ?? 'No file');
echo json_encode($response);
exit;
}
$tmpName = $_FILES['uploaded']['tmp_name'];
$origName = basename($_FILES['uploaded']['name']);
// 安全:生成唯一文件名
$ext = strtolower(pathinfo($origName, PATHINFO_EXTENSION));
$allowedExt = ['jpg', 'jpeg', 'png', 'gif'];
if (!in_array($ext, $allowedExt)) {
$response['message'] = 'Invalid file type';
echo json_encode($response);
exit;
}
$newName = uniqid('img_') . '.' . $ext;
$destPath = $targetDir . $newName;
if (move_uploaded_file($tmpName, $destPath)) {
$response['success'] = true;
$response['file'] = $newName;
$response['path'] = $destPath;
} else {
$response['message'] = 'Move failed: check directory permissions';
}
echo json_encode($response);
?>
// OkHttp
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("uploaded", file.getName(),
RequestBody.create(MediaType.parse("image/png"), file))
.addFormDataPart("userId", userId)
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override public void onResponse(Call call, Response response) {
// 處理響應
}
@Override public void onFailure(Call call, IOException e) { }
});
upload_tmp_dir 與目標目錄權限 (www-data 可讀寫)$_FILES['uploaded']['error'] 為 UPLOAD_ERR_OKMultipartEntity(HttpMultipartMode.STRICT)FileBody 明確指定 MIME 類型"uploaded" 前後端一致error_log / Nginx/Apache error.log)