GET 和 POST 请求

使用 XMLHttpRequest 和 fetch 发送 GET、POST 请求

问题

如何在 JavaScript 中发送 GET 和 POST 请求?

解答

使用 XMLHttpRequest

// GET 请求
function get(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open('GET', url, true)
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          resolve(JSON.parse(xhr.responseText))
        } else {
          reject(new Error(xhr.statusText))
        }
      }
    }
    xhr.onerror = () => reject(new Error('Network Error'))
    xhr.send()
  })
}

// POST 请求
function post(url, data) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open('POST', url, true)
    // 设置请求头
    xhr.setRequestHeader('Content-Type', 'application/json')
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          resolve(JSON.parse(xhr.responseText))
        } else {
          reject(new Error(xhr.statusText))
        }
      }
    }
    xhr.onerror = () => reject(new Error('Network Error'))
    // 发送 JSON 数据
    xhr.send(JSON.stringify(data))
  })
}

使用 fetch

// GET 请求
async function get(url) {
  const response = await fetch(url)
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`)
  }
  return response.json()
}

// POST 请求
async function post(url, data) {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  })
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`)
  }
  return response.json()
}

// 使用示例
get('https://api.example.com/users')
  .then(data => console.log(data))
  .catch(err => console.error(err))

post('https://api.example.com/users', { name: 'John', age: 25 })
  .then(data => console.log(data))
  .catch(err => console.error(err))

GET 和 POST 的区别

特性GETPOST
参数位置URL 查询字符串请求体
数据长度受 URL 长度限制(约 2KB)无限制
缓存可被缓存不会被缓存
安全性参数暴露在 URL 中参数在请求体中,相对安全
幂等性幂等(多次请求结果相同)非幂等
用途获取数据提交数据

关键点

  • XMLHttpRequest 通过 readyState === 4 判断请求完成,status 判断是否成功
  • fetch 返回 Promise,需要检查 response.ok 判断请求是否成功
  • POST 请求需要设置 Content-Type 请求头,并将数据放在请求体中
  • GET 请求参数拼接在 URL 上,POST 请求参数放在 body 中
  • fetch 不会因为 HTTP 错误状态码(如 404、500)而 reject,只有网络错误才会 reject