前端视角:Python requests vs JS axios

本文从前端视角切入,核心对比 Python requests 与 JS axios 在同步/异步模型、拦截器、取消请求及错误处理上的差异,加深理解。

作为前端开发者,我们每天都在用 axios 发请求,觉得它已经是 HTTP 请求的"标准答案"了。但如果你接触过 Python 后端,或者自己写过爬虫、脚本,大概率会碰到 requests 这个库。

一、它们是什么

Python requests JS axios
语言 Python JavaScript
运行环境 Python 环境(服务端/脚本 浏览器 + Node.js
编程模型 同步阻塞 异步非阻塞(基于 Promise)
安装 pip install requests npm install axios

最核心的区别就一句话:requests 是同步的,axios 是异步的。 这决定了它们在使用方式上的根本差异。

二、最基础的请求:写法对比

先看最简单的 GET 请求:

python 复制代码
# Python requests 
import requests 

response = requests.get('https://api.example.com/data') 
print(response.json()) # 直接拿到解析好的数据
javascript 复制代码
// JS axios 
import axios from 'axios' 

const response = await axios.get('https://api.example.com/data')
console.log(response.data) // 数据在 .data 里

看起来很像对吧?但注意两个细节:

  • requests 不需要 await,因为它本身就是同步的,代码执行到这一行会"卡住",等响应回来才继续
  • 响应数据的位置不同 :requests 用 response.json() 方法解析,axios 直接挂在 response.data

再看 POST 请求:

python 复制代码
# Python requests 
response = requests.post( 
    'https://api.example.com/users', 
    json={"name": "张三", "age": 25} # 自动序列化 + 设置 Content-Type
)
javascript 复制代码
// JS axios 
const response = await axios.post(
    'https://api.example.com/users', 
    { name: '张三', age: 25 } // 同样自动序列化 
)

两者都支持自动将对象序列化为 JSON 并设置 Content-Type: application/json,这点体验几乎一致。

三、同步 vs 异步:最本质的区别

这是前端同学最需要转变思维的地方。

requests 是同步阻塞的,意味着:

python 复制代码
import requests 

# 这行代码执行完之前,后面的代码不会执行 
response = requests.get('https://slow-api.com/data', timeout=10)
print('这行要等上面请求完成才会执行')

axios 是异步非阻塞的,基于 Promise:

javascript 复制代码
// 请求发出后,主线程不会被阻塞 
const response = await axios.get('https://slow-api.com/data')
console.log('等待请求完成后才执行')

这对前端来说是天经地义的------浏览器主线程不能被阻塞,否则页面就卡死了。但 Python 的 requests 天然就是"等完了再继续",写起来反而更直观,不需要理解 Promise、async/await 这些概念。

四、并发请求:体验差异明显

当你需要同时发多个请求时,差异就体现出来了。

axios 天然擅长并发 ,用 Promise.all 一行搞定:

javascript 复制代码
const [users, posts, comments] = await Promise.all([ 
    axios.get('/api/users'), 
    axios.get('/api/posts'),
    axios.get('/api/comments') 
])

requests 要实现并发,需要借助多线程或多进程:

python 复制代码
import requests 
from concurrent.futures import ThreadPoolExecutor

urls = ['/api/users', '/api/posts', '/api/comments']

with ThreadPoolExecutor(max_workers=3) as executor: 
    responses = list(executor.map(requests.get, urls))

或者使用 Python 的异步库(如 aiohttphttpx),但那就不是 requests 了。

五、拦截器 vs 没有拦截器

这是 axios 的一大杀手锏,也是前端工程化中非常常用的能力。

axios 的拦截器可以在请求发出前和响应返回后统一处理:

javascript 复制代码
// 请求拦截器:统一加 token 
axios.interceptors.request.use(config => { 
    config.headers.Authorization = `Bearer ${getToken()}` 
    return config 
}) 
// 响应拦截器:统一处理错误 
axios.interceptors.response.use( 
    response => response, 
    error => { 
        if (error.response?.status === 401) {
            // 跳转登录页 
        } 
        return Promise.reject(error) 
     } 
)

requests 没有原生的拦截器机制。要实现类似功能,需要自己封装:

python 复制代码
import requests 
class APIClient: 
    def __init__(self, base_url, token=None):
        self.session = requests.Session() 
        self.session.headers.update({ 
            'Authorization': f'Bearer {token}',
            'Accept': 'application/json'
        })
    def get(self, path, **kwargs):
        response = self.session.get(f'{base_url}{path}', **kwargs) 
        response.raise_for_status() 
        return response.json()

Session 对象可以实现"全局配置"的效果,但"拦截器"这种 AOP(面向切面)的能力,requests 确实不如 axios 优雅。

六、取消请求

前端场景中,取消请求很常见(比如用户快速切换页面时,取消上一个未完成的请求).

axios 通过 AbortController(早期版本用 CancelToken)实现:

javascript 复制代码
const controller = new AbortController() 

axios.get('/api/data', { signal: controller.signal }) 

// 需要取消时 
controller.abort()

requests 没有内置的取消机制。由于它是同步阻塞的,"取消"这个概念本身就不太适用------你只能通过设置 timeout 来控制最长等待时间。

七、错误处理:风格迥异

axios 基于 Promise,错误通过 .catch()try/catch 捕获:

javascript 复制代码
try { 
    const response = await axios.get('/api/data') 
} catch (error) { 
    if (error.response) { 
        console.log(`HTTP 错误: ${error.response.status}`)
    } else if (error.request) { 
        console.log('请求已发出,但没有收到响应')
    } else { 
        console.log('请求配置出错:', error.message) 
    } 
}

requests 基于异常(Exception),通过 try/except 捕获:

python 复制代码
try: 
    response = requests.get('/api/data', timeout=5) 
    response.raise_for_status() # 4xx/5xx 时主动抛出异常
except requests.exceptions.Timeout:
    print('请求超时') 
except requests.exceptions.ConnectionError:
    print('连接失败') 
except requests.exceptions.HTTPError as e:
    print(f'HTTP 错误: {e}')
except requests.exceptions.RequestException as e:
    print(f'其他异常: {e}')

两者的异常体系都是分层的(子类继承父类),但 requests 的异常层级更丰富,细分程度更高。

八、Session 机制对比

两者都支持"会话"概念,但实现方式不同:

requests.Session axios.create
连接复用 ✅ 底层连接池复用 TCP 连接 ✅ 浏览器端复用 HTTP 连接
Cookie 自动管理 ✅ 自动保存和携带 ✅ 浏览器端自动处理
全局默认配置 session.headers.update() instance.defaults.headers
自定义传输层 ✅ 可挂载 HTTPAdapter ❌ 不支持

requests 的 Session + HTTPAdapter 组合非常强大,可以精细控制连接池大小、重试策略等,这是 axios 做不到的。

九、功能特性速查表

特性 requests axios
同步/异步 同步 异步(Promise)
自动 JSON 序列化 json= 参数 ✅ 默认行为
请求拦截器 ❌ 需自行封装 ✅ 原生支持
响应拦截器 ❌ 需自行封装 ✅ 原生支持
取消请求 ✅ AbortController
并发请求 需多线程/多进程 Promise.all
连接池管理 ✅ HTTPAdapter
自动重试 ✅ HTTPAdapter max_retries ❌ 需自行封装
文件上传 files= 参数 FormData
浏览器环境
XSRF 防御 ❌ 需手动处理 ✅ 浏览器端自动处理

十、什么时候用哪个

用 axios 的场景(前端开发):

  • 浏览器端发请求,这是它的"主场"
  • 需要拦截器统一处理 token、错误码
  • 需要取消请求(如页面跳转时)
  • 需要并发请求(Promise.all

用 requests 的场景(Python 开发):

  • 写脚本、爬虫、自动化任务
  • 后端服务间调用
  • 对代码可读性要求高(同步写法更直观)
  • 需要精细控制连接池和重试策略
相关推荐
半个落月1 小时前
在浏览器里运行 DeepSeek-R1:React 对话界面与安全渲染(三)
前端·人工智能·react.js
Synmbrf1 小时前
micro-app 404 问题排查与修复
前端
西安栈上月明软件科技有限公司1 小时前
GEO 友好度检测器技术实现(已开源)
前端
哒哒哒5285201 小时前
69. Python: 核心语法-面向对象基础-案例(教务系统)
python
汉堡大王95271 小时前
用 Trae Work 自动化任务,6 分钟生成一份前端生态周报
前端·javascript·人工智能
深圳佛手1 小时前
安装DeepSeek Harness npx @deepseek-ai/dsh web 长时间没反应,安装失败,如何解决?
前端
何以解忧,唯有..1 小时前
Python 中获取目录操作完全指南
windows·python·microsoft
南京云森杉木桩1 小时前
常见打桩木品牌推荐,选对材质让工程更稳固
人工智能·python·材质
Csvn2 小时前
事件循环与渲染时机:一文吃透宏任务、微任务和 rAF
前端