问题描述
我在系统中引入axios,其实跟ajax没区别。但是只传递了业务参数,为什么能够通过认证,返回数据呢?
我看了下请求,是自带Cookie的呢,奇怪,我没有设置呀。
问题理解
问了问ai。
在 Axios 中,请求携带 Cookie 是由浏览器的同源策略和 Axios 配置共同决定的,与你代码中设置的 `x-requested-with` 头没有直接关系。具体来说:
1. **默认行为**:
当请求的 URL 与当前页面是**同源**(协议、域名、端口都相同)时,浏览器会自动在请求头中携带该域名下的 Cookie,无需额外配置。
2. **跨域请求携带 Cookie**:
如果是跨域请求(域名不同),需要同时满足两个条件才会携带 Cookie:
- 在 Axios 中配置 `withCredentials: true`
- 服务器响应头中包含 `Access-Control-Allow-Credentials: true`
3. 你的代码问题:
你在 `.then()` 的回调中才创建 `api` 实例,这是错误的——**请求已经发送完成,此时创建实例毫无意义**。正确的做法是先创建实例再发送请求:
```javascript
// 先创建实例并配置
const api = axios.create({
headers: {'x-requested-with': 'XMLHttpRequest'},
withCredentials: true // 跨域时需要添加这行
})
// 再发送请求
api.post('/detection/training/paper/list?' + objToUrlParams(this.queryParams))
.then(res => {
// 处理响应
})
```
总结:Cookie 是浏览器自动附加的(同源情况下),跨域时需要额外配置 `withCredentials`。你当前的代码由于实例创建位置错误,可能导致配置未生效。
我去,纸上得知终觉浅。原来这就是同源策略。同源会自动设置,Ajax 请求类似。
Ajax 请求(通常指原生 XMLHttpRequest)携带 Cookie 的机制与 Axios 类似,主要由浏览器的同源策略和请求配置决定:
### 1. 同源请求(同域名、协议、端口)
默认情况下,浏览器会自动在 Ajax 请求中携带当前域名下的 Cookie,无需额外配置。
示例:
```javascript
const xhr = new XMLHttpRequest();
xhr.open('POST', '/detection/training/paper/list?' + objToUrlParams(this.queryParams));
xhr.setRequestHeader('x-requested-with', 'XMLHttpRequest');
xhr.onload = function() {
// 处理响应
};
xhr.send(); // 同源时会自动携带 Cookie
```
### 2. 跨域请求(不同域名、协议或端口)
需要手动开启 **withCredentials** 配置,同时服务器需配合设置响应头:
- **客户端(Ajax)**:需设置 `xhr.withCredentials = true`
- **服务器**:需返回 `Access-Control-Allow-Credentials: true` 响应头,且 `Access-Control-Allow-Origin` 不能为 `*`(必须指定具体域名)
示例:
```javascript
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://other-domain.com/api/endpoint');
xhr.withCredentials = true; // 关键:允许跨域携带 Cookie
xhr.setRequestHeader('x-requested-with', 'XMLHttpRequest');
xhr.onload = function() {
// 处理响应
};
xhr.send();
```
### 总结
- 同源请求:Cookie 自动携带,无需额外配置
- 跨域请求:需同时满足
- 客户端设置 `xhr.withCredentials = true`
- 服务器设置 `Access-Control-Allow-Credentials: true` 且指定明确的 `Access-Control-Allow-Origin`
这与 Axios 的 `withCredentials: true` 配置原理一致,本质都是告诉浏览器在跨域时允许携带认证信息(包括 Cookie)。
如何设置上该参数?
这类令牌 Cookie 通常是**服务器在用户登录/验证通过后,通过 `Set-Cookie` 响应头设置**的,浏览器自动保存并在后续请求中携带。前端 JS 也可设置,但受更多安全限制,敏感令牌一般不建议前端手动设置。
在浏览器中设置类似 `PPUI` 这样的 Cookie(通常用作令牌或身份标识),主要通过两种方式实现:**服务器响应头设置** 或 **前端 JavaScript 直接操作**。
### 1. 服务器通过响应头 `Set-Cookie` 设置(最常见)
这是最标准、最安全的方式。当客户端(浏览器)向服务器发送请求后,服务器会在 HTTP 响应头中通过 `Set-Cookie` 字段将 Cookie 传递给浏览器,浏览器会自动保存并在后续请求中携带。
**示例流程**:
- 客户端发送登录请求(如提交用户名密码)。
- 服务器验证通过后,在响应头中添加:
```http
Set-Cookie: PPUI=00OWhqTjVjak9pUVdTeVYyYzFKQ0wyWVROd0FUTTNNRE0z...; Path=/; Domain=example.com; HttpOnly; Secure; SameSite=Lax
```
- 浏览器收到响应后,会自动将 `PPUI` Cookie 保存到本地(根据 `Domain` 和 `Path` 限制作用范围)。
- 后续客户端向该服务器发送请求时,浏览器会自动在请求头 `Cookie` 中携带该字段。
### 2. 前端通过 JavaScript 手动设置(`document.cookie`)
前端也可以直接通过 `document.cookie` API 手动设置 Cookie(受浏览器安全策略限制)。
**示例代码**:
```javascript
// 设置 PPUI Cookie
document.cookie = "PPUI=00OWhqTjVjak9pUVdTeVYyYzFKQ0wyWVROd0FUTTNNRE0z...; path=/; domain=example.com; max-age=86400; secure";
```
**参数说明**:
- `path=/`:Cookie 作用路径(整站有效)。
- `domain=example.com`:Cookie 作用域名(仅该域名下的页面可访问)。
- `max-age=86400`:有效期(秒),86400 表示 1 天。
- `secure`:仅在 HTTPS 协议下生效。
- `HttpOnly`:若添加此参数,前端 JavaScript 无法读取该 Cookie(更安全,防止 XSS 攻击)。
### 关键注意事项
1. **同源策略限制**:
- 通过 `document.cookie` 设置的 Cookie,`domain` 必须与当前页面域名一致(或为其父域名),否则设置失败。
- 服务器通过 `Set-Cookie` 可以设置跨域 Cookie,但需配合 CORS 配置(如 `Access-Control-Allow-Credentials`)。
2. **安全属性**:
- `HttpOnly`:建议对敏感令牌(如 `PPUI`)添加此属性,防止前端 JS 读取,降低 XSS 风险。
- `Secure`:仅在 HTTPS 环境下传递 Cookie,防止中间人攻击。
- `SameSite`:限制跨站请求携带 Cookie(如 `SameSite=Lax` 或 `SameSite=Strict`),防止 CSRF 攻击。
3. **有效期**:
- 若不设置 `max-age` 或 `expires`,Cookie 为“会话级”,关闭浏览器后自动失效。
- 若设置了有效期,则为“持久化 Cookie”,会保存到浏览器本地(如硬盘),直到过期。
### 总结
`PPUI` 这类令牌 Cookie 通常是**服务器在用户登录/验证通过后,通过 `Set-Cookie` 响应头设置**的,浏览器自动保存并在后续请求中携带。前端 JS 也可设置,但受更多安全限制,敏感令牌一般不建议前端手动设置。
问题总结
纸上得知终觉浅!!!