js 怎么发送AJAX请求

最现代且推荐的ajax请求方式是使用fetch api,1. 它基于promise,语法简洁,支持async/await,2. 可通过配置对象发送get/post请求并自定义请求头,3. 需手动检查response.ok处理http错误,4. 使用abortcontroller结合promise.race实现超时控制,5. 传统xmlhttprequest适用于需上传/下载进度、兼容老旧浏览器或同步请求的场景。遇到请求无响应时,应检查网络、cors、请求参数、代码逻辑及服务器状态。

在JavaScript中发送AJAX请求,最现代且推荐的方式是使用

fetch

API,它基于Promise,能更简洁地处理异步操作。当然,传统的

XMLHttpRequest

对象也依然可用,尤其在需要处理请求进度等特定场景时。

通过

fetch

API发送AJAX请求,其实比很多人想象的要直接。它返回一个Promise,让异步代码写起来更像同步。

最基本的GET请求是这样的:

fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) { // 检查HTTP状态码,确保请求成功
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json(); // 或response.text(),根据服务器返回的数据类型
  })
  .then(data => {
    console.log('获取到的数据:', data);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });

如果你需要发送POST请求,或者自定义请求头,

fetch

的第二个参数可以传入一个配置对象:

const postData = {
  name: '张三',
  age: 30
};

fetch('https://api.example.com/submit', {
  method: 'POST', // 请求方法
  headers: {
    'Content-Type': 'application/json', // 告诉服务器发送的是JSON数据
    'Authorization': 'Bearer your_token_here' // 认证信息
  },
  body: JSON.stringify(postData) // 将JavaScript对象转换为JSON字符串
})
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    console.log('服务器响应:', data);
  })
  .catch(error => {
    console.error('POST请求失败:', error);
  });

使用

async/await

语法会让代码看起来更整洁,尤其在处理多个异步操作时:

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    console.log('使用async/await获取到的数据:', data);
  } catch (error) {
    console.error('async/await请求失败:', error);
  }
}

fetchData();

而传统的

XMLHttpRequest

(XHR) 对象,虽然功能强大,但其API设计相对冗长:

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true); // 方法, URL, 是否异步
xhr.onload = function() {
  if (xhr.status >= 200 && xhr.status < 300) {
    console.log('XHR获取到的数据:', JSON.parse(xhr.responseText));
  } else {
    console.error('XHR请求失败,状态码:', xhr.status);
  }
};
xhr.onerror = function() {
  console.error('XHR网络错误');
};
xhr.send(); // 发送请求

为什么我的AJAX请求没有响应?

遇到AJAX请求没有响应的情况,通常是挺让人抓狂的,毕竟它不像同步代码那样会直接报错在当前行。这里面涉及的因素很多,从网络层面到代码逻辑,甚至服务器配置,都可能成为“罪魁祸首”。

首先,最常见的是网络问题。浏览器控制台的“Network”标签页是你的第一站。看看请求有没有发出?状态码是什么?如果是pending状态,可能是网络延迟或者请求被阻塞了。如果显示错误码,比如404(Not Found)、500(Internal Server Error),那问题显然出在服务器或URL上。

另一个高频问题是跨域资源共享(CORS)。当你尝试从一个域(比如

your-app.com

)向另一个域(比如

api.example.com

)发送AJAX请求时,浏览器会出于安全考虑阻止它,除非服务器明确允许。你会看到控制台报CORS相关的错误,比如“No 'Access-Control-Allow-Origin' header is present on the requested resource”。这需要后端在响应头中添加

Access-Control-Allow-Origin

等字段来允许你的前端域访问。前端能做的,除了检查请求头是否正确外,就是确保请求方式(GET/POST等)和服务器的CORS配置是匹配的。有时,复杂的请求(如带有自定义头或PUT/DELETE方法)会触发“预检请求”(OPTIONS方法),如果预检请求失败,主请求就不会发出。

请求参数或格式不正确也是个坑。比如,你期望发送JSON数据,但忘记设置

Content-Type: application/json

头,或者

body

内容不是有效的JSON字符串,服务器可能就无法解析。同样,如果后端期望接收表单数据,而你发送了JSON,也会导致解析失败。

再者,JavaScript代码逻辑错误。可能是URL拼写错误,或者异步操作没有正确地用

await

.then()

链式处理,导致你在数据还没回来的时候就去访问它。特别是新手,容易忘记

fetch

返回的是Promise,不处理它的解析结果就去用,那当然是拿不到数据。

最后,服务器端问题。即便前端代码完美无瑕,如果后端服务宕机、接口地址变更、数据库连接失败或者业务逻辑出错,请求也自然不会有预期的响应。这时候,就需要和后端开发沟通,或者查看服务器日志来定位问题。

AJAX请求中如何处理错误和超时?

处理AJAX请求中的错误和超时,是构建健壮应用不可或缺的一部分。我们不能指望网络永远畅通,服务器永远稳定。

对于错误处理

fetch

API的Promise特性让它变得相对直观。

fetch

本身只会在网络错误(如断网)或CORS问题时抛出错误,进入

.catch()

块。对于HTTP状态码(如404、500),

fetch

认为请求成功到达服务器,所以不会抛出错误,你需要手动检查

response.ok

属性(它等同于

response.status >= 200 && response.status < 300

)或者直接检查

response.status

fetch('https://api.example.com/non-existent-endpoint')
  .then(response => {
    if (!response.ok) {
      // HTTP状态码不在200-299范围内,手动抛出错误
      throw new Error(`服务器返回错误: ${response.status} ${response.statusText}`);
    }
    return response.json();
  })
  .then(data => {
    console.log('数据:', data);
  })
  .catch(error => {
    // 捕获网络错误、CORS错误或上面手动抛出的HTTP错误
    console.error('请求过程中发生错误:', error.message);
    // 可以根据错误类型进行不同的处理,比如显示用户友好的提示
    if (error.message.includes('404')) {
      alert('请求的资源不存在!');
    } else {
      alert('网络或服务器异常,请稍后再试。');
    }
  });

使用

async/await

时,

try...catch

结构是处理错误的最佳实践:

async function safeFetchData(url) {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP Error: ${response.status}`);
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('请求失败:', error);
    // 可以在这里进行错误上报或用户提示
    throw error; // 重新抛出错误,让调用者也能处理
  }
}

// 调用示例
safeFetchData('https://api.example.com/data')
  .then(data => console.log('成功获取:', data))
  .catch(err => console.error('最终处理:', err.message));

至于超时处理

fetch

API本身没有内置的超时选项,但可以通过

AbortController

Promise.race

来优雅地实现。

AbortController

允许你取消一个或多个

fetch

请求。

function fetchWithTimeout(url, options = {}, timeout = 5000) {
  const controller = new AbortController();
  const id = setTimeout(() => controller.abort(), timeout); // 设置一个定时器,超时后调用abort

  return fetch(url, {
    ...options,
    signal: controller.signal // 将AbortController的signal传递给fetch
  }).finally(() => clearTimeout(id)); // 无论成功失败,清除定时器
}

// 使用示例
fetchWithTimeout('https://api.example.com/slow-endpoint', {}, 3000) // 3秒超时
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    console.log('数据:', data);
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      console.error('请求超时或被取消:', error);
      alert('请求超时,请检查网络或稍后再试。');
    } else {
      console.error('其他请求错误:', error);
    }
  });

这种方式提供了一种灵活的超时控制机制,让你的应用在网络状况不佳时也能提供更好的用户体验。

何时选择XMLHttpRequest而不是Fetch API?

尽管

fetch

API无疑是现代Web开发中发送AJAX请求的首选,因为它基于Promise,语法更简洁,并且设计上更符合现代异步编程范式,但在某些特定场景下,

XMLHttpRequest

(XHR) 仍然有其存在的价值,或者说,在某些方面它提供了

fetch

API目前不具备的直接能力。

最主要的一个理由是上传/下载进度事件。如果你需要为文件上传或下载显示精确的进度条,

XMLHttpRequest

提供了

progress

事件,你可以监听

xhr.upload.onprogress

来获取上传进度,或者

xhr.onprogress

来获取下载进度。

fetch

API在处理这类事件上就显得力不从心了,因为它返回的是一个Promise,并且对底层的数据流处理做了抽象,直接获取进度信息并不方便(虽然可以通过ReadableStream来间接实现,但复杂度更高)。

另一个考虑因素是取消请求的兼容性。虽然

fetch

现在有了

AbortController

来取消请求,但这是一个相对较新的API,在一些非常老旧的浏览器环境中可能不被支持。而

XMLHttpRequest

abort()

方法则拥有更广泛的浏览器兼容性。当然,对于大多数现代Web应用来说,这不再是一个主要问题,因为

AbortController

的兼容性已经相当不错,并且可以通过polyfill来进一步提升。

再者,是同步请求。虽然强烈不推荐在主线程中使用同步AJAX请求(因为它会阻塞UI,导致页面卡死),但在Web Workers中,或者极少数特殊场景下,你可能需要一个同步的请求。

XMLHttpRequest

支持通过将

open()

方法的第三个参数设置为

false

来实现同步请求,而

fetch

API则完全是异步的,不提供同步模式。

最后,可能是一些遗留代码或特定库的依赖。在维护老项目时,如果它们已经大量使用了

XMLHttpRequest

,并且没有明显的性能或功能瓶颈,那么继续沿用它可能比重构为

fetch

更划算。一些第三方库可能也基于XHR构建,直接使用它们的API比自己封装

fetch

更方便。

总的来说,对于绝大多数日常的API交互、数据获取和提交,

fetch

API都是更优的选择,因为它更符合JavaScript的异步特性,代码更具可读性和可维护性。只有当你明确需要XHR特有的功能(如精细的上传下载进度条)或者必须兼容非常老的浏览器环境时,才需要考虑

XMLHttpRequest

以上就是js 怎么发送AJAX请求的详细内容,更多请关注骃骐网【www.myinqi.com】。

相关推荐:

如何高效流式读取大型CSV文件并异步发送HTTP请求

本文介绍针对20GB级CSV文件的内存友好型流式处理方案,通过csv.DictReader逐行解析、aiohttp并发控制与XML模板填充,实现低内存占用、高吞吐量的HTTP批量提交。 本文介绍针对20gb级csv文件的内存友好型流式处理方案,通过`csv.dictreader`逐行解析、`aiohttp`并发控制与xml模板填充,实现低内存占用、高吞吐量的http批量提交。 处理超大CSV文件(...

如何解决Python爬虫请求频繁被重定向的问题_设置allow_redirects参数

requests.get() 默认自动跳转(allow_redirects=True)会导致爬虫失效,因反爬系统常利用301/302跳转至验证码页或空页,使你无法获取原始响应头和状态码,进而中断后续逻辑。 为什么 requests.get() 默认会自动跳转,反而导致爬虫失效 因为 requests 默认开启重定向追踪(allow_redirects=True),遇到 301、302 响应时会自动...

如何解决Python爬虫在长连接请求中超时的问题_设置合理的timeout参数与重试机制

requests.get()默认不设超时会无限等待,必须用timeout=(connect, read)元组分别控制连接与读取超时,单数值仅作用于读取阶段,连接阶段仍可能卡死。 requests.get() 默认不设超时,长连接请求卡住几小时都可能不报错——必须显式设置 timeout,且不能只填一个数字。 为什么单个 timeout 数值对长连接无效 requests 的 timeout 参数若...

如何在Flask中集成百度地图API_通过Python后端转发请求处理跨域

前端不能直接调用百度地图API,因为AK必须绑定域名白名单,写在前端会暴露密钥导致盗用、配额超限或封禁;后端转发核心是保护密钥,而非绕过跨域,所有带AK的接口均需服务端中转。 为什么不能让前端直接调用百度地图API 因为百度地图JavaScript API强制要求使用ak(Access Key)且该密钥**仅限绑定域名白名单**,而一旦把ak写在前端代码里,就等于公开暴露——别人抓包就能盗用,触发...

Python爬虫怎么抓取动态更新的API数据_使用轮询机制请求接口

轮询前需先判断接口是否真需轮询:若API支持增量拉取(如含timestamp参数或last_updated字段)或缓存机制(ETag/If-Modified-Since),应优先采用;否则才考虑轮询,并需封装为可中断、带重试、超时控制与随机抖动的健壮循环。 轮询接口前先确认它是否真需要轮询 很多所谓“动态更新”的数据,其实只是前端用 fetch 或 axios 调了后端 API,而这个 API 本...

Python中如何实现异步DNS解析_通过aiodns提升大规模并发请求效率

aiodns 因底层基于 c-ares 实现纯异步 DNS 查询,不依赖系统 getaddrinfo,故在高并发下更可控稳定;而 asyncio.getaddrinfo 在 Linux 等平台常同步阻塞,易卡住事件循环,导致延迟突增、CPU 升高。 aiodns 是目前 Python 中最轻量、最直接支持异步 DNS 解析的第三方库,它底层封装了 c-ares,不依赖事件循环的 DNS 实现(比如...

怎样在Python Flask中获取Header请求头信息_使用request.headers

在Flask中应使用request.headers.get("Header-Name")安全读取请求头,该对象大小写不敏感、类字典,键不存在时返回None;自定义头需确保代理(如Nginx)透传,调试时可用dict(request.headers)打印全部头信息。 如何在Flask中正确读取 request.headers request.headers 是一个类字典对象(Headers 类型),...

SOAP消息示例?一个完整请求响应过程?

SOAP请求响应过程始于客户端构造包含操作和参数的XML消息并发送至服务端,服务端解析后执行业务逻辑,再返回包含结果或错误信息的SOAP响应,客户端接收后解析并处理结果或异常。 SOAP消息是基于XML的,用于在分布式环境中交换结构化信息的协议,通常通过HTTP承载。一个完整的SOAP请求响应过程,简单来说,就是客户端按照特定格式构造XML消息发送给服务端,服务端处理后,再以XML消息格式返回结果...