### 彪哥

爱好前端

- 初识 TypeScript

- TypeScript 常用语法

- ts-axios 项目初始化

- ts-axios 基础功能实现

- ts-axios 异常情况处理

- ts-axios 接口扩展

- ts-axios 拦截器实现

- ts-axios 配置化实现

- ts-axios 取消功能实现

- ts-axios 更多功能实现

  - withCredentials
    - 需求分析
    - 代码实现
    - demo 编写
  - XSRF 防御
  - 上传和下载的进度监控
  - HTTP 授权
  - 自定义合法状态码
  - 自定义参数序列化
  - baseURL
  - 静态方法扩展

- ts-axios 单元测试

- ts-axios 部署与发布

- 《TypeScript 从零实现 axios》
- ts-axios 更多功能实现

HuangYi
2020-01-05
目录

# withCredentials

# # withCredentials

## # 需求分析

有些时候我们会发一些跨域请求，比如 `http://domain-a.com` 站点发送一个 `http://api.domain-b.com/get` 的请求，默认情况下，浏览器会根据同源策略限制这种跨域请求，但是可以通过 CORS
(opens new window) 技术解决跨域问题。

在同域的情况下，我们发送请求会默认携带当前域下的 cookie，但是在跨域的情况下，默认是不会携带请求域下的 cookie 的，比如 `http://domain-a.com` 站点发送一个 `http://api.domain-b.com/get` 的请求，默认是不会携带 `api.domain-b.com` 域下的 cookie，如果我们想携带（很多情况下是需要的），只需要设置请求的 `xhr` 对象的 `withCredentials` 为 true 即可。

## # 代码实现

先修改 `AxiosRequestConfig` 的类型定义。

`types/index.ts`：

    export interface AxiosRequestConfig {
      // ...
      withCredentials?: boolean
    }

1
2
3
4

然后修改请求发送前的逻辑。

`core/xhr.ts`：

    const { /*...*/ withCredentials } = config

    if (withCredentials) {
      request.withCredentials = true
    }

1
2
3
4
5

## # demo 编写

在 `examples` 目录下创建 `more` 目录，在 `cancel` 目录下创建 `index.html`:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>More example</title>
      </head>
      <body>
        <script src="/__build__/more.js"></script>
      </body>
    </html>

1
2
3
4
5
6
7
8
9
10

接着创建 `app.ts` 作为入口文件：

    import axios from '../../src/index'

    document.cookie = 'a=b'

    axios.get('/more/get').then(res => {
      console.log(res)
    })

    axios.post('http://127.0.0.1:8088/more/server2', { }, {
      withCredentials: true
    }).then(res => {
      console.log(res)
    })

1
2
3
4
5
6
7
8
9
10
11
12
13

这次我们除了给 `server.js` 去配置了接口路由，还创建了 `server2.js`，起了一个跨域的服务。

    const express = require('express')
    const bodyParser = require('body-parser')
    const cookieParser = require('cookie-parser')

    const app = express()

    app.use(bodyParser.json())
    app.use(bodyParser.urlencoded({ extended: true }))
    app.use(cookieParser())

    const router = express.Router()

    const cors = {
      'Access-Control-Allow-Origin': 'http://localhost:8080',
      'Access-Control-Allow-Credentials': true,
      'Access-Control-Allow-Methods': 'POST, GET, PUT, DELETE, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type'
    }

    router.post('/more/server2', function(req, res) {
      res.set(cors)
      res.json(req.cookies)
    })

    router.options('/more/server2', function(req, res) {
      res.set(cors)
      res.end()
    })

    app.use(router)

    const port = 8088
    module.exports = app.listen(port)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

这里需要安装一下 `cookie-parser` 插件，用于请求发送的 cookie。

通过 demo 演示我们可以发现，对于同域请求，会携带 cookie，而对于跨域请求，只有我们配置了 `withCredentials` 为 true，才会携带 cookie。

至此我们的 `withCredentials` feature 开发完毕，下一节课我们来实现 axios 对 XSRF 的防御功能。

编辑
(opens new window)
#TypeScript
上次更新: 2022/12/14, 19:36:42
取消功能的设计与实现
XSRF 防御

← 取消功能的设计与实现 XSRF 防御→

最近更新

  01
Git修改分支名
08-11

  02
CSS给table的tbody添加滚动条
06-29

  03
我做了一个手写春联小网页，祝大家虎年暴富 原创
01-28

更多文章>

Copyright © 2016-2022 Hesb | MIT License

- 跟随系统
- 浅色模式
- 深色模式
- 阅读模式