原来我误会了 changeOrigin 那么多年

简介: 前端开发中经常要配置接口代理服务,用来解决开发阶段的跨域问题。有一个常用的 changeOrigin 配置项,它究竟配置了个啥?本文做了一个小小的探究。

changeOrigin 到底改了啥

前端开发中经常要配置接口代理服务,用来解决开发阶段的跨域问题。

无论是 webpack-dev-server 中的 proxy,还是 vite 中的 proxy,内部都是使用了同一个库 node-http-proxy

一个代理的例子

在配置 proxy 时,通常是这样的:

// vite.config.js

import { defineConfig } from 'vite'

export default defineConfig({
  server: {
    // 配置代理服务
    proxy: {
      // 以 /api 开头的请求,全部转发到 target 设置的地址
      '/api': {
        target: 'https://demo.com',
        changeOrigin: true
      }
    }
  }
})

设置 target 目标的同时,有时还会配置一个 changeOrigin 属性。看名字,它好像用来改变 origin 请求头的值,将其改为 target 的值。

真的如此吗?

先看文档

  • changeOrigin: true/false, Default: false - changes the origin of the host header to the target URL

也就是说,changeOrigin 的默认值为 false,用来将 host 请求头修改为 target 的 URL

🌰 通过一个例子演示

准备两个服务:

  • 后端:使用 koa 创建的接口服务
  • 前端:使用 @vue/cli 创建的 vue 项目

示例代码已上传到 Github 仓库

Koa

在本地 3000 端口启动一个接口服务:

// server.js

const Koa = require("koa")
const body = require("koa-body")
const Router = require("@koa/router")

const app = new Koa()
const router = new Router()

app.use(body())

// post请求,携带 origin 头
router.post('/api/list', async ctx => {
    console.log(ctx.headers)
    ctx.body = {
        code: 0,
        msg: 'ok'
    }
})

app.use(router.routes()).use(router.allowedMethods());

app.listen(3000, () => {
    console.log(`服务器已启动: 3000`);
})

Vue

前端使用 axios 访问接口/api/list

// main.js

import axios from 'axios'

axios.post('/api/list').then(res => {
  console.log(res)
})

设置 changeOrigin 为 false

devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: false
      }
    }
}

此时的 originhost 头分别是:

Host: localhost:8080

Origin: http://localhost:8080

image-20221007233456329

可以通过代理解决跨域问题:

image-20221007233601051

服务端接收到的请求头信息是:

origin: 'http://localhost:8080'

host: 'localhost:8080'

image-20221007233800986

设置 changeOrigin 为 true

devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true
      }
    }
}

浏览器端查看请求头信息:

Host: localhost:8080

Origin: http://localhost:8080

image-20221007233901503

服务端接收到的请求头信息:

origin: 'http://localhost:8080'

host: 'localhost:3000'

image-20221007233943164

发现

这一次,host 头的值变为 localhost:3000 ,也就是 target 设置的接口服务器的地址了。

也就是,changeOrigin 这个配置项,修改的不是 origin 头,而是 host 头。

那么,修改 host 有什么特别的作用吗?

答案是没有。起码对于解决跨域问题没有。

换个角度看, changeOrigin 的默认值是 false,也就是不改,说明不改的适用场景更广泛一些。

那如果改了 host ,能发挥出什么作用吗?

那就先看看 host 这个头本身的作用是什么。

host header

Host 请求头表示请求资源的网络主机和端口号, 比如我们访问上面的 localhost:8080 这个页面,那么它的 host 就是:
image-20221008161006384

该请求头在 HTTP/1.1 版本中推出,是为了解决虚拟主机的问题。在 HTTP/1.0 中,一个域名绑定一个 IP 地址,一台服务器对应一个 IP,因此一台服务器只能运行一个站点。随着虚拟主机技术的发展,有时候需要在一台服务器上运行多个虚拟主机,此时服务器就可以通过 host 头来做不同的处理。

在运行 HTTP/1.1 协议的网站中,请求头中要求携带 host 头。现在很多网站都已经支持了 HTTP/2 版本协议,它就不要求携带 host 请求了。

看下百度:

image-20221008004414723

看下主域名:

image-20221008004535987

掘金已经全部采用 HTTP/2 了:

image-20221008004745061

已经没有 host 请求头了:

image-20221008005019850

小结

配置 changeOrigin 修改 host,基本上没什么用。

🎀 关于 changeOrigin 的结论

通过上面的探究,基本可以得出以下结论:

  1. changeOrigin 配置项用来修改 host header,而非 origin header
  2. Host header 用来处理虚拟主机的问题,和跨域无关
  3. 一般情况下,设置代理时可以忽略这个配置项,保持默认即可
  4. 特殊情况下,很可能后端服务就用 host 做校验了,此时根据实际情况去设置

另一个问题:为什么浏览器网络面板观察不到 host 的修改?

因为浏览器运行的 js 代码,发出了一个网络请求,这个请求的 host 就是 localhost:8080

发出去之后,被本地的代理服务拦截到了,在这个地方将 host 修改了,再发往后端服务器。

也就是,host 修改时,浏览器已经将请求发出去了,所以观察不到。

🏁 最后

本文简单探讨了 changeOrigin 这个常见的配置项。用了这么多年,才发现一直“误会”了它。看来正应了那句老话:

纸上得来终觉浅,

绝知此事要躬行。

目录
相关文章
|
人工智能 运维 安全
职等你来 | 2023春招,牵手阿里云基础设施,期待同行
快~加入阿里云基础设施,一起打开有意思的未来!
职等你来 | 2023春招,牵手阿里云基础设施,期待同行
|
存储 云安全 人工智能
有多难?直击传统行业的“云上再创业”之路
有多难?直击传统行业的“云上再创业”之路
512 0
有多难?直击传统行业的“云上再创业”之路
|
人工智能 Kubernetes 数据可视化
专注低代码 17 年,Mendix 公司如何在“争议”中继续前行 | 卓越技术团队访谈录
“任何平台只要是图灵完备的、逻辑自洽的,并且可以做到从无代码、低代码、全代码三种开发方式无缝衔接的都不能把它称为毒瘤。”Mendix 公司中国研发中心上海团队的技术负责人周勇说道。
230 0
|
移动开发 人工智能 前端开发
素人程序员:如何在技术浪潮更迭中保持较高成长速度?
  技术更迭是有加速度的,一个又一个风口,一波又一波浪潮,昨天火了人工智能,今天已经大谈区块链。普通程序员们在这个进程里,应该怎样找准自己的位置,获得持续的个人成长呢?   技术更迭是有加速度的   从 2010 年开始,被定义为移动互联网的元年,移动开发也是从这一年开始逐渐开始火爆的。笔者也是从毕业之后加入这个浪潮的。据说移动开发火爆之时,理发师通过几个月培训以后也可以拿到月薪 1,2W 的薪水,可见那个时候对移动人才的饥渴程度。但是到了 2014 年底开始,移动开发的入职要求回归理性,要求逐渐提高,到现在基本大公司社招也不再招高级以下的移动开发了。
156 0
|
云安全 存储 运维
想转行加入云计算行业的同学看这里
近年来,云计算市场前景火爆,越来越多的企业将业务迁移到云上,云计算人才也成为企业高薪招聘的对象。有人看到这一点,就想转行加入云计算行业。
438 0
想转行加入云计算行业的同学看这里
|
Web App开发 存储 移动开发
思考、创新、坚持——阿里做了七年前端,我的成长经验分享
在成长的未知道路上,我们总会遇到各种各样的问题,但是,所有的迷茫与逆境都能够帮助我们成长,我们要抓住每一个机会让自己进步,而不是徘徊不前。 淘系前端开发同学——林晚,今天就来和大家分享他这七年的成长经历,以及如何摆脱业务前端的职业迷茫感。
2880 0
思考、创新、坚持——阿里做了七年前端,我的成长经验分享
阿里专家五年方法论总结!技术人如何实现职业突破?
带你看七篇阿里专家五年的方法论总结!指导技术人应对复杂的业务与代码,如何实现突破职业。
14006 0
|
API 虚拟化 云计算
|
存储 监控 关系型数据库
众安保险五年的云计算故事
作为首家获得互联网牌照的保险公司,众安保险与云计算携手走过了5年的时间,这五年的时间内,众安保险见证了阿里云的成长和成熟,也走出了属于自己的一条上云之路,那么众安保险云上的数据库设计有哪些故事呢?本文中,众安保险数据库负责人钟海平将为大家揭晓。
3204 0