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

纸上得来终觉浅,

绝知此事要躬行。

非常抱歉对您的问题理解有误。如果您已经自己重写了QChartView类,并想要在其中实现改变点的大小,您可以通过重写paintEvent()方法来实现。 下面是一个示例代码,展示了如何在自定义的QChartView类中改变点的大小: ```cpp class CustomChartView : public QChartView { public: CustomChartView(QChart *chart, QWidget *parent = nullptr) : QChartView(chart, parent) {} protected: void paintEvent(QPaintEvent *event) override { QChartView::paintEvent(event); // 获取图表对象 QChart *chart = this->chart(); if (!chart) return; // 遍历图表中的系列 QList<QAbstractSeries *> seriesList = chart->series(); for (QAbstractSeries *series : seriesList) { // 判断是否为散点系列 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series); if (scatterSeries) { // 设置点的大小 scatterSeries->setMarkerSize(10); // 设置点的大小为10像素 } } } }; ``` 在这个示例中,我们创建了一个名为CustomChartView的自定义QChartView类,并重写了其paintEvent()方法。在paintEvent()方法中,我们首先获取图表对象,然后遍历图表中的系列。如果发现某个系列是散点系列,则设置其点的大小为10像素。 然后,您可以使用CustomChartView来替代原来的QChartView对象,以实现设置点的大小的功能。只需将图表对象设置到CustomChartView中,然后将CustomChartView作为窗口部件添加到应用程序中即可: ```cpp QChart *chart = new QChart(); // 创建系列并添加数据点 QScatterSeries *scatterSeries = new QScatterSeries(); scatterSeries->append(0, 0); scatterSeries->append(1, 1); scatterSeries->append(2, 2); chart->addSeries(scatterSeries); CustomChartView *chartView = new CustomChartView(chart); chartView->setRenderHint(QPainter::Antialiasing); // 将CustomChartView作为窗口部件添加到应用程序中 // ... ``` 这样,您应该能够在自定义的QChartView类中成功实现改变点的大小的功能。请注意,在paintEvent()方法中,我们只处理了散点系列(QScatterSeries),您可以根据需要进行适当的修改和扩展。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昆吾kw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值