一、AJAX基本原理。
1.通过XmlHttpRequest向服务器发异步请求。
2.获取到数据后,操作DOM更新页面。
3.期间无需刷新整个页面。
XHR实例:
--XmlHttpRequest
--ActiveXObject("Microsoft.XMLHTTP")
--ActiveXObject("msxml2.XMLHTTP")
XHR关键方法:--xhrReq.open(method,url,async);
--xhrReq.setRequestHeader(header,value);
--xhrReq.send(data);
--xhrReq.onreadystatechange
代码示例:
javascript
var xhr;
//W3C浏览器创建XmlHttpRequest对象
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
//IE浏览器创建XmlHttpRequest对象
if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
try {
xhr = new ActiveXObject("msxml2.XMLHTTP");
} catch (ex) {}
}
}
if (!xhr) {
alert("创建xhr对象异常!");
return;
}
xhr.open("POST", '/counter');
xhr.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
$('#result').append('<div>' + xhr.responseText + '</div>');
}
}
}
xhr.send('sadfsafsafasfasfda');
二、AJAX与后端HTTP请求的区别
AJAX(Asynchronous JavaScript and XML)与后端HTTP请求是Web开发中两个紧密相关但又有所区别的概念。理解它们的区别有助于更好地进行前后端交互设计。
1. 概念与定位
AJAX :是一种在浏览器端使用的技术,它允许JavaScript在不重新加载整个页面的情况下,通过XMLHttpRequest或Fetch API与服务器进行异步数据交换。
后端HTTP请求 :通常指服务器端程序(如Java、Python、Node.js等)向其他服务器或服务发起的HTTP请求,用于获取数据、调用API或进行服务间通信。
2. 发起位置
- AJAX:由运行在用户浏览器中的JavaScript发起。
- 后端HTTP请求:由运行在服务器上的后端程序发起。
3. 技术实现
AJAX:主要使用浏览器内置的XMLHttpRequest对象或现代的Fetch API。
javascript
// AJAX示例(使用Fetch API)
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
后端HTTP请求:使用服务器端语言的HTTP客户端库,如Java的HttpClient、Python的requests、Node.js的axios或内置的http模块。
javascript
// Node.js后端HTTP请求示例(使用axios)
const axios = require('axios');
axios.get('https://api.example.com/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error:', error);
});
4. 主要区别对比
| 对比维度 | AJAX | 后端HTTP请求 |
|---|---|---|
| 发起环境 | 浏览器/客户端 | 服务器端 |
| 主要目的 | 实现页面局部更新,提升用户体验 | 服务间通信、数据聚合、API调用 |
| 可见性 | 用户可见(可通过开发者工具查看) | 对用户透明,在服务器端完成 |
| 同源策略限制 | 受浏览器同源策略限制(可通过CORS解决) | 通常不受同源策略限制 |
| 安全性 | 需防范XSS、CSRF等前端安全风险 | 需处理服务器间认证、数据安全 |
| 性能影响 | 影响客户端响应速度和用户体验 | 影响服务器处理能力和响应时间 |
5. 实际应用场景
AJAX典型场景:
- 表单提交后的局部验证反馈
- 无限滚动加载更多内容
- 实时搜索建议(如搜索框自动补全)
- 聊天应用的消息发送与接收
- 单页面应用(SPA)的路由切换与数据加载
后端HTTP请求典型场景:
- 服务器调用第三方API(如支付接口、地图服务)
- 微服务架构中的服务间通信
- 数据爬取与聚合
- 服务器端渲染(SSR)时获取数据
- 定时任务中的数据同步
6. 相互关系
在实际Web应用中,AJAX与后端HTTP请求常常协同工作:
- 用户操作触发浏览器中的AJAX请求
- 请求发送到应用的后端服务器
- 后端服务器处理请求,可能再向其他服务发起HTTP请求
- 后端服务器将处理结果返回给浏览器
- 浏览器通过AJAX回调函数更新页面
例如,一个电商网站的购物车功能:用户点击"加入购物车"(AJAX)→ 后端服务器验证库存(后端HTTP请求调用库存服务)→ 返回结果给前端 → 前端更新购物车图标数量。
7. 总结
AJAX关注的是浏览器与服务器之间的异步通信 ,旨在提升用户体验;后端HTTP请求关注的是服务器与其他服务之间的通信,旨在实现业务逻辑和数据整合。两者在Web开发中各有其不可替代的作用,理解它们的区别有助于选择合适的技术方案。
AJAX由浏览器发起,自动添加必须的请求头:User- Agent,Referer,Cookie,受浏览器限制,存在跨域问题。
后端发起HTTP请求,请求头一般需要自行添加,没有特殊限制,不存在跨域问题。
三、AJAX实现类库
除了使用原生的 XMLHttpRequest 和 Fetch API,开发者还可以借助各种成熟的 JavaScript类库来简化AJAX请求的编写,提升开发效率和代码可维护性。这些类库通常提供了更简洁的API、更好的浏览器兼容性、请求/响应拦截器、Promise支持、自动JSON转换等特性。
1. jQuery AJAX
jQuery 是早期最流行的 JavaScript 库,其 $.ajax() 方法极大地简化了 AJAX 操作,并解决了浏览器兼容性问题。
javascript
// 使用 jQuery 发起 GET 请求
$.ajax({
url: '/api/data',
method: 'GET',
dataType: 'json',
success: function(data) {
console.log('请求成功:', data);
},
error: function(xhr, status, error) {
console.error('请求失败:', error);
}
});
// 更简洁的写法
$.get('/api/data', function(data) {
console.log(data);
});
// 发送 POST 请求
$.post('/api/submit', { name: 'John', age: 30 }, function(response) {
console.log('提交成功:', response);
});
特点:
- 语法简洁,链式调用。
- 自动处理浏览器兼容性(如 IE)。
- 支持 JSONP 跨域。
- 在现代前端开发中逐渐被更轻量的方案取代。
2. Axios
Axios 是一个基于 Promise 的 HTTP 客户端,可用于浏览器和 Node.js,是目前最流行的 AJAX 库之一。
javascript
// 安装:npm install axios
import axios from 'axios';
// 发起 GET 请求
axios.get('/api/user/123')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
// 发起 POST 请求
axios.post('/api/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(response => {
console.log(response);
});
// 使用 async/await
async function getUser() {
try {
const response = await axios.get('/api/user/123');
console.log(response.data);
} catch (error) {
console.error(error);
}
}
特点:
- 支持 Promise API。
- 拦截请求和响应。
- 自动转换 JSON 数据。
- 客户端支持防御 XSRF。
- 可取消请求。
3. Fetch API(现代原生方案)
Fetch API 是现代浏览器原生提供的 AJAX 方案,返回 Promise,语法更现代。虽然它不是第三方库,但常与类库对比。
javascript
// 基本 GET 请求
fetch('/api/data')
.then(response => {
if (!response.ok) {
throw new Error('网络响应异常');
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('请求失败:', error));
// 使用 async/await
async function fetchData() {
try {
const response = await fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ key: 'value' }),
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
特点:
- 原生支持,无需额外库。
- 基于 Promise,支持 async/await。
- 更灵活的流式处理能力。
- 默认不发送/接收 cookies,需显式配置。
- 错误处理机制与 jQuery/Axios 不同(不会对 HTTP 错误状态码 reject)。
4. SuperAgent
SuperAgent 是一个轻量级、可链式调用的客户端 HTTP 请求库,在 Node.js 和浏览器中均可使用。
javascript
// 浏览器中使用
const request = require('superagent');
request
.get('/api/search')
.query({ q: 'JavaScript' })
.then(res => {
console.log(res.body);
})
.catch(err => {
console.error(err);
});
// 链式调用设置
request
.post('/api/pet')
.send({ name: 'Manny', species: 'cat' })
.set('X-API-Key', 'foobar')
.set('Accept', 'application/json')
.then(res => {
console.log('上传成功');
});
特点:
- 链式语法,可读性强。
- 插件系统丰富。
- 支持文件上传、进度事件等。
5. 其他类库
- Got:Node.js 端流行的 HTTP 请求库,设计优雅。
- Request(已弃用):曾是 Node.js 最常用的 HTTP 客户端,现已不推荐使用。
- Ky:基于 Fetch 的轻量级封装,提供更简单的 API 和更好的错误处理。
- umi-request:蚂蚁金服基于 Fetch 封装的请求库,集成中间件、拦截器等特性。
6. 如何选择?
| 类库/API | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| jQuery AJAX | 老项目维护、需要兼容旧版 IE | 兼容性好,API 简单 | 体积大,现代项目中逐渐淘汰 |
| Axios | 现代 Web 应用、需要拦截器、取消请求等高级功能 | 功能全面,Promise 支持好,社区活跃 | 需要额外引入 |
| Fetch API | 现代浏览器项目、追求零依赖 | 原生支持,无需安装,语法现代 | 兼容性需 polyfill,错误处理稍繁琐 |
| SuperAgent | Node.js 和浏览器同构应用 | 链式语法优雅,插件丰富 | 知名度不如 Axios |
总结建议:
- 新项目推荐使用 Axios 或原生的 Fetch API。
- 若项目已依赖 jQuery,可继续使用
$.ajax。 - Node.js 后端请求可考虑 Axios 或 Got。
- 选择时需考虑浏览器兼容性、项目体积、团队熟悉度等因素。
7.问题:GET请求过来的内容不变如何处理?
--在URL后面加时间戳
--jQuery.ajax使用cache: false
--服务端设置Cache- Control: no- cache,清除Last-Modified等缓存相关的相应头。
四、jsonp跨域详解
1.JSON with Padding
2.利用<script>标签的src不受同源策略限制,向不同域发http请求,得到一段可执行的js,这段js将相应数据作为参数调用回调函数。
图解:

jQuery中的实现,直接在$.ajax中设置相关字段
- dataType: "jsonp"
- jsonp: 设置url中回调函数名称的字段名
- jsonpCallback: 不设置里,jQuery自动生成回调函数名;设置为固定值,则回调函数名为该固定值;设置为函数,则回调函数名为该函数的返回值
JSONP的问题:远程网站有 js 注入漏洞,原来网站也会受到影响
远程网站需要考虑跨站请求伪造攻击
jsonp 不支持 post 请求,只能发 get 请求
那么,如果要发post请求,一般用什么方法做跨域?
对于 POST 请求的跨域,最常用且推荐的方法是 CORS(跨域资源共享)。CORS 是 W3C 标准,通过在服务端设置响应头来允许跨域请求,支持 GET、POST、PUT、DELETE 等所有 HTTP 方法。
服务端配置示例(以 Node.js/Express 为例):
javascript
// 使用 cors 中间件
const express = require('express');
const cors = require('cors');
const app = express();
// 允许所有来源(开发环境)
app.use(cors());
// 或指定允许的来源
app.use(cors({
origin: 'https://your-frontend-domain.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true // 允许携带 Cookie
}));
app.post('/api/data', (req, res) => {
res.json({ message: 'POST 跨域请求成功' });
});
关键响应头说明:
Access-Control-Allow-Origin:指定允许的源(如https://example.com或*)Access-Control-Allow-Methods:允许的 HTTP 方法(需包含 POST)Access-Control-Allow-Headers:允许的自定义请求头Access-Control-Allow-Credentials:是否允许携带 Cookie
前端配合示例(使用 Fetch API 发送 POST 跨域请求):
javascript
fetch('https://api.example.com/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: '张三', age: 25 }),
credentials: 'include' // 携带 Cookie
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('跨域请求失败:', error));
其他辅助方案:
- 代理服务器:在开发环境中通过 Webpack Dev Server 或 Nginx 配置反向代理,将跨域请求转发到目标服务器,从而绕过浏览器的同源策略。
- postMessage + iframe :通过隐藏 iframe 加载目标域页面,利用
window.postMessage进行跨域通信,但实现较复杂,不推荐作为首选。
总结: 对于 POST 跨域请求,CORS 是标准、安全且最广泛使用的方案。只需在服务端配置相应的响应头,前端正常发送 POST 请求即可。代理服务器适合开发调试阶段,生产环境仍建议使用 CORS。