原来我误会了 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
      }
    }
  }
})
AI 代码解读

设置 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`);
})
AI 代码解读

Vue

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

// main.js

import axios from 'axios'

axios.post('/api/list').then(res => {
  console.log(res)
})
AI 代码解读

设置 changeOrigin 为 false

devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: false
      }
    }
}
AI 代码解读

此时的 originhost 头分别是:

Host: localhost:8080

Origin: http://localhost:8080
AI 代码解读

image-20221007233456329

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

image-20221007233601051

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

origin: 'http://localhost:8080'

host: 'localhost:8080'
AI 代码解读

image-20221007233800986

设置 changeOrigin 为 true

devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true
      }
    }
}
AI 代码解读

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

Host: localhost:8080

Origin: http://localhost:8080
AI 代码解读

image-20221007233901503

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

origin: 'http://localhost:8080'

host: 'localhost:3000'
AI 代码解读

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 这个常见的配置项。用了这么多年,才发现一直“误会”了它。看来正应了那句老话:

纸上得来终觉浅,

绝知此事要躬行。

目录
打赏
0
0
0
0
41
分享
相关文章
学习笔记 | 技术创业之路: 从架构师走向创业者
学习笔记 | 技术创业之路: 从架构师走向创业者
374 0
阿里 10 年:一个普通技术人的成长之路
不管是什么角色,成长是我们每个人都必须经历的过程。作为一个技术人,成长不仅是技术上的不断精进,也包括日常工作中的方方面面。本文主要讲述了阿里巴巴高级技术专家在阿里 10 年的成长之路,分享他从一个普通技术人开始,在阿里的三个阶段,以及在晋升、转岗、带团队、做事等方面的心得感悟。
阿里 10 年:一个普通技术人的成长之路
阿里10年:一个普通技术人的成长之路
不管是什么角色,成长是我们每个人都必须经历的过程。作为一个技术人,成长不仅是技术上的不断精进,也包括日常工作中的方方面面。本文分享阿里巴巴高级技术专家在阿里10年的成长之路,分享他从一个普通技术人开始,在阿里的三个阶段,以及在晋升、转岗、带团队、做事等方面的心得感悟。
阿里10年:一个普通技术人的成长之路
五年成为阿里技术专家,架构师需要懂哪些技术?
  很早很早之前,我对于架构的概念一点都不理解,依稀记得,架构( architecture)这个词,来自于建筑领域。   这对于我这个没写过几行代码的人来说,瞬间就有了一种“不明觉厉”的崇拜感。   架构,感觉好厉害的样子,从名称上来说,好像是设计根骨,设计底层,设计最核心的东西的人。   架构师,一定很NB,我什么时候能成为架构师呢?   后来懂了一点点代码,去写增删改查,更是体会不出来架构的概念,不就是Sql语句吗?明明DBA更厉害啊,做各种的慢Sql优化,所有的Sql都要让DBA审核,DBA对于Mysql,或者是Oracle的各种性能调忧很厉害,而熟悉业务的开发人员又常常能写出几
250 0
思考、创新、坚持——阿里做了七年前端,我的成长经验分享
在成长的未知道路上,我们总会遇到各种各样的问题,但是,所有的迷茫与逆境都能够帮助我们成长,我们要抓住每一个机会让自己进步,而不是徘徊不前。 淘系前端开发同学——林晚,今天就来和大家分享他这七年的成长经历,以及如何摆脱业务前端的职业迷茫感。
3017 0
思考、创新、坚持——阿里做了七年前端,我的成长经验分享
技术人的灵魂 3 问,阿里工程师如何解答?
在业务团队做事的工程师摸爬滚打了一段时间后,一定会有所疑问。团队同学在最初的一段时间都提出这样的疑惑:如何在业务中发现有技术价值的问题?发现问题后如何思考和发起再到解决?最后的技术结果跟业务结果如何衔接?很多时候我们听别人说“思考是不够的/要多思考”,其实都是在说这几点。接下来,阿里高级前端技术专家氐宿谈一谈遇到这三个问题时,他是如何解决的?
技术人的灵魂 3 问,阿里工程师如何解答?
阿里5年,我的成长历程
我是阿里巴巴钉钉事业部,宜搭生产力平台的普通开发。我是2015年校招应届生进入阿里的小硕,和众多学子一样,一早就在准备各个大厂的秋招,幸运的是顺利地拿到了阿里的offer,成为一名踏入职场的技术人。转眼间已经在职场摸爬滚打5年了,回首往事却历历在目,遂对我在阿里的成长历程做了一个阶段性的梳理和小结,对自己是一种鼓励,如果能对读者有一丝帮助也是极好的了。
632 0
专访小邪:从十年技术之路看阿里技术体系的变革
从2008年到2018年,从阿里巴巴中间件团队到飞天八部——小邪与阿里的十年。
9703 0
我的多年上云之路
聊起上云,往事不堪回首,已然过去很久,而今已为云栖版主。 初识 多年前,当初还在上初中,对互联网的了解才刚刚从课本、以及老师的口中知道,原来互联网这么丰富,可以查阅资料可以下载游戏,当时语文课要查找诗词的翻译,通过搜索看到好多的站点,打开页面呈现给我一种铺面而来的好奇,接着我跟着课程注册邮箱
5499 0
《运维工程师成长之路》—— 导读
随着国内电商行业的发展和壮大,运维工作也变得更加复杂。为了保证系统及应用稳定、高效地运行,企业需要有更多的高级运维工程师。服务器的稳定运行是企业发展较为重要的基础,当前国内大部分中小企业对运维工程师的定位就是“打杂的”,但随着技术型公司的诞生及成长,运维工程师的发展空间将会越来越大。
1979 0
《运维工程师成长之路》—— 导读

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等