Skip to content

Ajax使用簡介

AJAX(Asynchronous JavaScript and XML)是一種用於在不重新加載整個網頁的情況下,與伺服器交換資料的技術。這使得網頁可以動態更新部分內容,而不必完全重新載入頁面。儘管名字中包含 XML,但 AJAX 可以使用多種格式交換資料,例如 JSON、HTML、XML 或純文字。

以下是有關 AJAX 在 JavaScript 中的使用方式的詳細說明:

1. AJAX 的核心概念

AJAX 通常通過 XMLHttpRequest 物件來實現,XMLHttpRequest 是一個原生的 JavaScript 物件,用於與伺服器交換資料。

但在現代瀏覽器中,fetch API 是一個更簡潔和現代的替代方案。

2. 使用 XMLHttpRequest

2.1 建立 XMLHttpRequest 物件

首先,你需要創建一個 XMLHttpRequest 物件:

let xhr = new XMLHttpRequest();

2.2 配置請求

使用 open 方法來配置請求的類型、URL 和是否異步:

xhr.open("GET", "https://api.example.com/data", true);
* "GET" 是請求的方法,可以是 "GET" 或 "POST"。 * 第二個參數是請求的 URL。 * 第三個參數是布林值,true 表示異步,false 表示同步。

2.3 設置請求頭(可選)

如果需要設置請求頭,例如發送 JSON 資料,可以使用 setRequestHeader 方法:

xhr.setRequestHeader("Content-Type", "application/json");

2.4 處理伺服器的響應

onreadystatechange 是一個事件處理器,在請求的不同階段被調用。常用的做法是檢查 readyState 是否為 4(請求完成),並檢查 status 是否為 200(成功)。

xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        // 成功處理伺服器的回應
        let response = JSON.parse(xhr.responseText);
        console.log(response);
    }
};

2.5 發送請求

最後,使用 send 方法發送請求。如果是 GET 請求,send 參數留空;如果是 POST 請求,可以在 send 中傳遞要發送的數據。

xhr.send();
如果是 POST 請求,傳遞 JSON 數據可能如下:
let data = JSON.stringify({ name: "John", age: 30 });
xhr.send(data);

3. 使用 Fetch API

fetch 是現代 JavaScript 的一部分,是對 XMLHttpRequest 的替代方案,並且提供了更簡潔的語法和基於 Promise 的處理方式。

3.1 基本的 GET 請求

fetch 返回一個 Promise,它會解析為 Response 物件。

fetch("https://api.example.com/data")
    .then(response => {
        if (!response.ok) {
            throw new Error("Network response was not ok " + response.statusText);
        }
        return response.json(); // 解析為 JSON
    })
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error("There has been a problem with your fetch operation:", error);
    });

3.2 基本的 POST 請求

發送 POST 請求時,你需要在 fetch 中傳遞一個配置對象,包括 methodheadersbody

fetch("https://api.example.com/data", {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({ name: "John", age: 30 })
})
    .then(response => {
        if (!response.ok) {
            throw new Error("Network response was not ok " + response.statusText);
        }
        return response.json(); // 解析為 JSON
    })
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error("There has been a problem with your fetch operation:", error);
    });

4. 處理不同的資料格式

  • JSON:最常見的資料格式,使用 response.json() 來解析。
    fetch("https://api.example.com/data")
        .then(response => response.json())
        .then(data => console.log(data));
    
  • 文本(Text):使用 response.text() 來解析。
    fetch("https://api.example.com/data")
        .then(response => response.text())
        .then(text => console.log(text));
    
  • Blob:用於處理二進制數據,如圖片或文件,使用 response.blob()
    fetch("https://api.example.com/image")
        .then(response => response.blob())
        .then(blob => {
            let img = document.createElement("img");
            img.src = URL.createObjectURL(blob);
            document.body.appendChild(img);
        });
    
  • FormData:用於處理表單數據,尤其是在上傳文件時。
    let formData = new FormData();
    formData.append("username", "JohnDoe");
    formData.append("file", fileInput.files[0]);
    
    fetch("https://api.example.com/upload", {
        method: "POST",
        body: formData
    })
        .then(response => response.json())
        .then(data => console.log(data));
    

5. 處理 CORS(跨域資源共享)

如果請求的資源來自不同的網域,則可能會遇到 CORS 問題。伺服器需要設置正確的 Access-Control-Allow-Origin 標頭來允許跨域請求。

fetch("https://another-domain.com/api", {
    method: "GET",
    mode: "cors"
})
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error("CORS error:", error));

6. AJAX 載入部分網頁內容

AJAX 可以用來動態載入網頁的一部分內容,而不重新載入整個頁面。

document.getElementById("loadButton").addEventListener("click", function() {
    fetch("content.html")
        .then(response => response.text())
        .then(html => {
            document.getElementById("contentArea").innerHTML = html;
        })
        .catch(error => console.error("Error loading content:", error));
});

7. 處理異常

fetch API 不會像 XMLHttpRequest 那樣自動拒絕 Promise 即使是 404 或 500 等錯誤狀態。你需要自己檢查 response.okresponse.status

fetch("https://api.example.com/data")
    .then(response => {
        if (!response.ok) {
            throw new Error("Network response was not ok");
        }
        return response.json();
    })
    .catch(error => {
        console.error("Fetch error:", error);
    });

8. AJAX 與 JSONP

在跨域請求還沒有通過 CORS 之前,開發者常使用 JSONP(JSON with Padding)來繞過跨域限制。這種技術通過動態生成一個 <script> 標籤來加載伺服器上的 JSON 資料。然而,JSONP 只支援 GET 請求,而且不安全,現在已經不推薦使用,應該優先使用 fetch 和 CORS。

9. 使用 Promise.all 並行多個 AJAX 請求

如果需要並行發送多個 AJAX 請求,可以使用 Promise.all 來等待所有請求完成後再處理結果。

let request1 = fetch("https://api.example.com/data1").then(response => response.json());
let request2 = fetch("https://api.example.com/data2").then(response => response.json());

Promise.all([request1, request2])
    .then(results => {
        let data1 = results[0];
        let data2 = results[1];
        console.log(data1, data2);
    })
    .catch(error => {
        console.error("Error with one of the requests:", error);
    });

10. AJAX 與前端框架

在現代前端開發中,AJAX 通常與 React、Vue、Angular 等框架一起使用,並且可以利用 Axios 這樣的第三方庫來簡化 AJAX 操作。

使用 Axios 的範例:

axios.get("https://api.example.com/data")
    .then(response => console.log(response.data))
    .catch(error => console.error("Error:", error));

總結來說,AJAX 是一項強大的技術,它能夠讓網頁更加動態和互動。隨著 fetch API 的出現,處理 AJAX 請求變得更加簡單和現代化。學會這些技術能夠極大地提升你的前端開發能力。