AJAX 简介

AJAX 是什么、XMLHttpRequest 的工作流程、同步与异步。

Beginner
Key PointsAJAX 让页面在不刷新的情况下向服务器要数据:创建 XHR、发请求、在回调里更新 DOM。

四步流程

JavaScript
const xhr = new XMLHttpRequest();          // 1. 创建
xhr.open('GET', 'data.asp?q=asp');        // 2. 配置
xhr.onreadystatechange = function () {    // 3. 监听
  if (xhr.readyState === 4 && xhr.status === 200) {
    document.getElementById('out').textContent = xhr.responseText;
  }
};
xhr.send();                               // 4. 发送
readyStateMeaning
0还没调用 open
1open 调过了
2请求已发出
3收到部分响应
4响应全部到达

fetch 写法

JavaScript
const res = await fetch('data.asp?q=asp');
if (!res.ok) throw new Error('HTTP ' + res.status);
const text = await res.text();
document.getElementById('out').textContent = text;

fetch is the modern replacement, Promise-based and much shorter. Note it does not reject on 404/500 — only on network failure — so check res.ok yourself.

POST 提交 JSON

JavaScript
const res = await fetch('save.asp', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Ada', age: 36 })
});
const data = await res.json();
ASP
<%
    Response.ContentType = "application/json"
    Response.Charset = "UTF-8"

    ' 经典 ASP 没有内置 JSON 解析,需自己读请求体
    Dim body
    body = Request.BinaryRead(Request.TotalBytes)
    ' 或用第三方 JSON 库解析 body

    Response.Write "{""ok"":true}"
%>

Request.Form cannot read an application/json body; it only parses form encodings. Receiving JSON needs BinaryRead plus your own parser — the awkward part of AJAX in classic ASP.

同步 vs 异步

JavaScript
// 异步(默认):不阻塞,界面照常响应
xhr.open('GET', 'slow.asp', true);

// 同步:浏览器会卡住直到响应到达(已不推荐,主线程会被警告)
xhr.open('GET', 'slow.asp', false);

A synchronous request freezes the page: no clicks, no scrolling, no animation. Modern browsers warn about synchronous XHR on the main thread and forbid it in some contexts. Always use async.

An AJAX endpoint should return data, not a chunk of HTML. Returning <table>...</table> for innerHTML looks convenient but invites XSS and makes the data unusable elsewhere.

跨域

JavaScript
// 请求别的域名时,浏览器会先发 OPTIONS 预检
fetch('https://api.other.com/data', { credentials: 'include' });
ASP
<%
    Response.AddHeader "Access-Control-Allow-Origin", "https://app.example.com"
    Response.AddHeader "Access-Control-Allow-Methods", "GET, POST, OPTIONS"
    Response.AddHeader "Access-Control-Allow-Headers", "Content-Type"
    Response.AddHeader "Access-Control-Allow-Credentials", "true"

    If Request.ServerVariables("REQUEST_METHOD") = "OPTIONS" Then
        Response.End
    End If
%>

Access-Control-Allow-Origin: * cannot be combined with credentials. To send cookies you must name the exact origin — no wildcards.

Friends & Partners