首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP + JavaScript 實現異步圖片上傳:FormData + XMLHttpRequest 完整範例

     編輯:PHP 綜合知識

現代瀏覽器支援 `FormData` + `XMLHttpRequest Level 2` 實現無刷新檔案上傳,支援進度條、多檔、二進位傳輸。本文提供極簡後端接收與前端上傳邏輯,無第三方依賴。

後端 upload.php

<?php
if (isset($_FILES["myfile"])) {
    $ret = [];
    $uploadDir = 'images' . DIRECTORY_SEPARATOR . date("Ymd") . DIRECTORY_SEPARATOR;
    $dir = __DIR__ . DIRECTORY_SEPARATOR . $uploadDir;

    // 遞迴建立目錄並設權限
    if (!file_exists($dir)) {
        mkdir($dir, 0777, true);
        chmod($dir, 0777);
    }

    if (!is_array($_FILES["myfile"]["name"])) {
        // 單檔上傳
        $ext = pathinfo($_FILES["myfile"]["name"], PATHINFO_EXTENSION);
        $fileName = time() . uniqid() . '.' . $ext;
        move_uploaded_file($_FILES["myfile"]["tmp_name"], $dir . $fileName);
        $ret['file'] = DIRECTORY_SEPARATOR . $uploadDir . $fileName;
    }
    // 多檔支援可在此擴充

    header('Content-Type: application/json');
    echo json_encode($ret);
}
?>

前端 index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>HTML5 Ajax 檔案上傳</title>
    <style>
        .txt { height:28px; border:1px solid #cdcdcd; width:670px; }
        .mybtn { background:#fff; line-height:14px; vertical-align:middle; border:1px solid #cdcdcd; height:30px; width:70px; }
        .file { position:absolute; top:0; right:80px; height:24px; opacity:0; filter:alpha(opacity:0); width:260px; }
    </style>
</head>
<body>
    <div class="form-group">
        <label>圖片</label><br/>
        <input type="text" name="textfield" id="textfield" class="txt" readonly />
        <span onclick="file.click()" class="mybtn">瀏覽...</span>
        <input type="file" name="file" class="file" id="file" size="28" 
            onchange="document.getElementById('textfield').value=this.value" />
        <span onclick="UpladFile()" class="mybtn">上傳</span>
    </div>

    <script>
    var xhr;
    function createXMLHttpRequest() {
        if (window.ActiveXObject) {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        } else if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest();
        }
    }

    function UpladFile() {
        var fileObj = document.getElementById("file").files[0];
        if (!fileObj) { alert("請選擇檔案"); return; }

        var form = new FormData();
        form.append("myfile", fileObj);

        createXMLHttpRequest();
        xhr.onreadystatechange = handleStateChange;
        xhr.open("post", "upload.php", true);
        xhr.send(form);
    }

    function handleStateChange() {
        if (xhr.readyState == 4) {
            if (xhr.status == 200 || xhr.status == 0) {
                var result = xhr.responseText;
                var json = eval("(" + result + ")"); // 或 JSON.parse(result)
                alert('圖片連結:\n' + json.file);
            }
        }
    }
    </script>
</body>
</html>

關鍵技術點

技術說明
FormData自動構建 multipart/form-data 體,支援檔案、欄位混合
XMLHttpRequest Level 2支援 `upload.onprogress` 事件,可做進度條
input[type=file] 隱藏opacity:0 覆蓋在自訂按鈕上,美化 UI
JSON 回應結構化回傳路徑、錯誤碼、訊息,前端易處理

進階擴展

  1. 上傳進度條:
    xhr.upload.onprogress = function(e) {
        if (e.lengthComputable) {
            var percent = Math.round((e.loaded / e.total) * 100);
            document.getElementById('progress').style.width = percent + '%';
        }
    };
  2. 多檔上傳:`` + 迴圈 `fileObj.files` append;
  3. 檔案類型/大小驗證:前端 `fileObj.type`、`fileObj.size` 攔截 + 後端二次驗證;
  4. 錯誤處理:`xhr.onerror`、HTTP 狀態碼判斷、JSON `error` 欄位;
  5. 取消上傳:`xhr.abort()`;
  6. 現代寫法:`fetch()` + `FormData` + `async/await` 更簡潔。

相容性提醒

  • IE10+ 完整支援;
  • IE9 以下無 `FormData`、`File API`,需用 `