Skip to content

Conversation

@cyfung1031
Copy link
Collaborator

@cyfung1031 cyfung1031 commented Dec 16, 2025

很多腳本也有用 response.responseHeaders.split("\r\n")

https://github.com/search?q=+responseHeaders.split%28%22%5Cr%5Cn%22%29&type=code

// ==UserScript==
// @name         GMXhr - Header Response
// @namespace    http://tampermonkey.net/
// @version      2025-12-16
// @description  try to take over the world!
// @author       You
// @match        https://example.com/?header_response_sc
// @icon         https://www.google.com/s2/favicons?sz=64&domain=github.com
// @grant        GM_xmlhttpRequest
// @connect      translate.googleapis.com
// ==/UserScript==

(function() {
    'use strict';

    GM_xmlhttpRequest({
        method: "GET",
        responseType: "blob",
        headers: {},
        url: "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=ja&dj=1&dt=t&dt=rm&q=%E3%81%8F%E3%82%8B%EF%BC%81%EF%BC%81%0A%E3%81%8F%E3%82%8B%E2%80%A6%0A%E3%81%8D%E3%81%9F%EF%BC%81%EF%BC%81%0Alets+go%0A%E3%81%8F%E3%82%8B%EF%BC%81%0Ayes%21",
        onload: function (response) {
            console.log("Header Response", JSON.stringify([response.responseHeaders]));
        },
    });


    // Your code here...
})();

@cyfung1031 cyfung1031 added P0 🚑 需要紧急处理的内容 hotfix 需要尽快更新到扩展商店 labels Dec 16, 2025
@cyfung1031 cyfung1031 marked this pull request as draft December 16, 2025 05:39
@CodFrm
Copy link
Member

CodFrm commented Dec 16, 2025

另外感觉TM返回的headers的是不是排序了?(这个我觉得没必要也跟随了)

@cyfung1031 cyfung1031 marked this pull request as ready for review December 16, 2025 06:08
@cyfung1031
Copy link
Collaborator Author

另外感觉TM返回的headers的是不是排序了?

有注意到。但感觉 TM 不是故意用了 sort.
有可能是在 sendMessage 用 object 传了所以 key 自动 sort了

(这个我觉得没必要也跟随了)

对。如果加 sort 会拖慢

@cyfung1031 cyfung1031 marked this pull request as draft December 16, 2025 06:20
this.responseURL = res.url ?? this.url;
this._responseHeaders = {
getAllResponseHeaders(): string {
let ret: string | undefined = this.cache[""];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个cache的key怎么是 空文本

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有 key 的是单一 header (getResponseHeader). 空 key 是 all (getAllResponseHeaders)
只是用了同一个 cache 来处理
当然不好看的话也可以拆开做多一个 variable

@cyfung1031 cyfung1031 marked this pull request as ready for review December 16, 2025 07:09
Co-Authored-By: wangyizhi <yz@ggnb.top>
Comment on lines 375 to 406
export const nativeResponseHeadersTreatment = (headersString: string) => {
if (!headersString) return "";
const len = headersString.length;
let out = "";
let start = len; // start position = nil
let separator = "";
for (let i = 0; i <= len; i++) {
const char = headersString.charCodeAt(i) || 10;
if (char === 10 || char === 13) {
if (i > start) {
const seg = headersString.substring(start, i); // "key: value"
const j = seg.indexOf(":");
if (j > 0) {
let k = j + 1;
if (seg.charCodeAt(k) === 32) k++;
if (k < seg.length) {
const headerName = seg.substring(0, j); // "key"
const headerValue = seg.substring(k); // "value"
out += `${separator}${headerName}:${headerValue}`;
separator = "\r\n";
}
}
}
start = len; // start position = nil
} else {
if (start === len) {
start = i; // set start position
}
}
}
return out;
};
Copy link
Member

@CodFrm CodFrm Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

真心希望使用可读性更好的方式去实现,虽然大概明白是个什么逻辑,也处理了很多异常的情况,当然不是说不好,我觉得很厉害,但是阅读起来好困难

我们拿到的header应该是浏览器已经处理过一遍的header,而且http协议应该也不允许那种异常的header,按照http协议来说,结尾一定是 \r\n

https://developer.mozilla.org/zh-CN/docs/Glossary/HTTP_header

看你吧

// TM Xhr Header 兼容处理,原生xhr \r\n 在尾,但TM的GMXhr没有;同时除去冒号后面的空白
export const nativeResponseHeadersTreatment = (headersString: string) => {
  if (!headersString) return "";
  let out = "";
  let separator = "";
  headersString.split(/\r?\n/).forEach((line) => {
    const j = line.indexOf(":");
    if (j > 0) {
      const headerName = line.substring(0, j); // "key"
      let headerValue = line.substring(j + 1); // "value"
      let k = 0;
      // 删除开头空白
      for (; k < headerValue.length; k += 1) {
        if (headerValue[k] !== " ") {
          break;
        }
      }
      headerValue = headerValue.substring(k);
      out += `${separator}${headerName}:${headerValue}`;
      separator = "\r\n";
    }
  });
  return out;
};

Copy link
Collaborator Author

@cyfung1031 cyfung1031 Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

headersString.split(/\r?\n/)

不想用 regex. 效能考虑

Copy link
Member

@CodFrm CodFrm Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

做了个基准测试,好像性能并不好。。。。。:

  ✓ src/pkg/utils/utils.bench.ts > nativeResponseHeadersTreatment 基准测试 8784ms
     name                          hz     min     max    mean     p75     p99    p995    p999     rme   samples
   · 简单响应头               2,731,094.40  0.0002  5.7630  0.0004  0.0003  0.0004  0.0006  0.0010  ±4.16%   1365548
   · 包含多余空格的响应头          1,931,481.53  0.0004  0.4018  0.0005  0.0005  0.0006  0.0011  0.0015  ±0.50%    965741
   · 复杂真实场景响应头             468,745.09  0.0020  0.2766  0.0021  0.0021  0.0025  0.0028  0.0062  ±0.26%    234373
   · 混合分隔符响应头            1,495,232.50  0.0005  0.9980  0.0007  0.0006  0.0015  0.0015  0.0016  ±0.84%    747617
   · 空字符串               24,717,513.26  0.0000  0.9977  0.0000  0.0000  0.0000  0.0000  0.0001  ±0.51%  12358757
   · 长响应头 (100个header)      54,875.94  0.0171  0.5177  0.0182  0.0175  0.0199  0.0340  0.4157  ±1.03%     27438

 BENCH  Summary

  空字符串 - src/pkg/utils/utils.bench.ts > nativeResponseHeadersTreatment 基准测试
    9.05x faster than 简单响应头
    12.80x faster than 包含多余空格的响应头
    16.53x faster than 混合分隔符响应头
    52.73x faster than 复杂真实场景响应头
    450.43x faster than 长响应头 (100个header)
 ✓ src/pkg/utils/utils.bench.ts > nativeResponseHeadersTreatment 基准测试 8989ms
     name                          hz     min     max    mean     p75     p99    p995    p999     rme   samples
   · 简单响应头               3,731,787.16  0.0001  0.6287  0.0003  0.0003  0.0004  0.0007  0.0010  ±1.05%   1865894
   · 包含多余空格的响应头          2,648,493.16  0.0002  8.9453  0.0004  0.0003  0.0004  0.0006  0.0010  ±4.20%   1324247
   · 复杂真实场景响应头             793,283.50  0.0011  0.5739  0.0013  0.0012  0.0017  0.0019  0.0034  ±0.64%    396642
   · 混合分隔符响应头            2,360,763.12  0.0003  3.7784  0.0004  0.0004  0.0005  0.0010  0.0011  ±1.77%   1180382
   · 空字符串               23,601,426.73  0.0000  0.2814  0.0000  0.0000  0.0001  0.0001  0.0001  ±0.30%  11800714
   · 长响应头 (100个header)     102,675.98  0.0087  0.8815  0.0097  0.0090  0.0103  0.0197  0.3522  ±1.40%     51338

 BENCH  Summary

  空字符串 - src/pkg/utils/utils.bench.ts > nativeResponseHeadersTreatment 基准测试
    6.32x faster than 简单响应头
    8.91x faster than 包含多余空格的响应头
    10.00x faster than 混合分隔符响应头
    29.75x faster than 复杂真实场景响应头
    229.86x faster than 长响应头 (100个header)
import { bench, describe } from "vitest";
import { nativeResponseHeadersTreatment } from "./utils";

describe("nativeResponseHeadersTreatment 基准测试", () => {
  // 测试用例1: 简单的响应头
  const simpleHeaders = "content-type: application/json\r\nserver: nginx";

  // 测试用例2: 包含多余空格的响应头
  const headersWithSpaces = "content-type:    application/json\r\nserver:   nginx\r\ncache-control:  no-cache";

  // 测试用例3: 复杂的响应头(真实场景)
  const complexHeaders = `content-type: text/html; charset=utf-8\r\n
server: Apache/2.4.41 (Ubuntu)\r\n
set-cookie: sessionid=abc123; Path=/; HttpOnly\r\n
cache-control: no-store, no-cache, must-revalidate\r\n
expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n
pragma: no-cache\r\n
x-frame-options: SAMEORIGIN\r\n
x-content-type-options: nosniff\r\n
content-security-policy: default-src 'self'\r\n
access-control-allow-origin: *`;

  // 测试用例4: 包含多种分隔符的响应头(混合 \r\n 和 \n)
  const mixedHeaders = "content-type: application/json\nserver: nginx\r\ncache-control: no-cache\ncontent-length: 1234";

  // 测试用例5: 空字符串
  const emptyHeaders = "";

  // 测试用例6: 很长的响应头(性能压力测试)
  const longHeaders = Array(100)
    .fill(0)
    .map((_, i) => `x-custom-header-${i}:   value-${i}`)
    .join("\r\n");

  bench("简单响应头", () => {
    nativeResponseHeadersTreatment(simpleHeaders);
  });

  bench("包含多余空格的响应头", () => {
    nativeResponseHeadersTreatment(headersWithSpaces);
  });

  bench("复杂真实场景响应头", () => {
    nativeResponseHeadersTreatment(complexHeaders);
  });

  bench("混合分隔符响应头", () => {
    nativeResponseHeadersTreatment(mixedHeaders);
  });

  bench("空字符串", () => {
    nativeResponseHeadersTreatment(emptyHeaders);
  });

  bench("长响应头 (100个header)", () => {
    nativeResponseHeadersTreatment(longHeaders);
  });
});

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我再看看

Copy link
Collaborator Author

@cyfung1031 cyfung1031 Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

呀。測試方法有問題
對同一個 string 做 regex, V8內部會cache 起來

bench(...) 會跑同一個N次
第一次是真時間,第2~N次都是假的

let atomicId = 0;
  bench("简单响应头", () => {
    nativeResponseHeadersTreatment(`${++atomicId}${simpleHeaders}`);
  });

  bench("包含多余空格的响应头", () => {
    nativeResponseHeadersTreatment(`${++atomicId}${headersWithSpaces}`);
  });

  bench("复杂真实场景响应头", () => {
    nativeResponseHeadersTreatment(`${++atomicId}${complexHeaders}`);
  });

  bench("混合分隔符响应头", () => {
    nativeResponseHeadersTreatment(`${++atomicId}${mixedHeaders}`);
  });

  bench("长响应头 (100个header)", () => {
    nativeResponseHeadersTreatment(`${++atomicId}${longHeaders}`);
  });

我估計上面是 regex 下面是我的版本
你會看到 上面的 max 很大

Copy link
Member

@CodFrm CodFrm Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你的写法和思路更像是在弄 C/C++ ,不过说实话,哪怕是性能更好,我也宁愿牺牲掉这么一点微不足道的性能换取可读性,可读性差加大了其他人的阅读门槛,类似的问题我提了好多次了,后续我可能要重新思考这些为了性能妥协的内容了 😣

当然也不是说性能问题不重要,只是不用在这种很细小的问题上去钻,一般都是在量级上来了后才会体现出问题来,而且这个量级几乎不会达到。

就我来说,一般只会考虑实际情况可能会达到一定量级的地方,才会特意的去做性能优化

Copy link
Collaborator Author

@cyfung1031 cyfung1031 Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { bench, describe } from "vitest";

// TM Xhr Header 兼容处理,原生xhr \r\n 在尾,但TM的GMXhr没有;同时除去冒号后面的空白
export const nativeResponseHeadersTreatment1 = (hs: string) => {
  let start = 0;
  let out = "";
  const len = hs.length;
  let separator = "";
  while (start < len) {
    const i = hs.indexOf(":", start); // 冒号的位置
    let j = hs.indexOf("\n", start); // 换行符的位置
    if (j < 0) j = len; // 尾行
    if (i < j) {
      const key = hs.substring(start, i).trim(); // i 为 -1 的话 key 也会是空值
      if (key) {
        out += `${separator}${key}:${hs.substring(i + 1, j).trim()}`;
        separator = "\r\n";
      }
    }
    start = j + 1; // 移到下一行
  }
  return out;
};

export const nativeResponseHeadersTreatment2 = (headersString: string) => {
  if (!headersString) return "";
  let out = "";
  let separator = "";
  headersString.split(/\r?\n/).forEach((line) => {
    const j = line.indexOf(":");
    if (j > 0) {
      const headerName = line.substring(0, j); // "key"
      let headerValue = line.substring(j + 1).trim(); // "value"
      let k = 0;
      // 删除开头空白
      for (; k < headerValue.length; k += 1) {
        if (headerValue[k] !== " ") {
          break;
        }
      }
      headerValue = headerValue.substring(k);
      out += `${separator}${headerName}:${headerValue}`;
      separator = "\r\n";
    }
  });
  return out;
};

describe("nativeResponseHeadersTreatment 基准测试", () => {
  // 测试用例1: 简单的响应头
  const simpleHeaders = "content-type: application/json\r\nserver: nginx";

  // 测试用例2: 包含多余空格的响应头
  const headersWithSpaces = "content-type:    application/json\r\nserver:   nginx\r\ncache-control:  no-cache";

  // 测试用例3: 复杂的响应头(真实场景)
  const complexHeaders = `content-type: text/html; charset=utf-8\r\n
server: Apache/2.4.41 (Ubuntu)\r\n
set-cookie: sessionid=abc123; Path=/; HttpOnly\r\n
cache-control: no-store, no-cache, must-revalidate\r\n
expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n
pragma: no-cache\r\n
x-frame-options: SAMEORIGIN\r\n
x-content-type-options: nosniff\r\n
content-security-policy: default-src 'self'\r\n
access-control-allow-origin: *`;

  // 测试用例4: 包含多种分隔符的响应头(混合 \r\n 和 \n)
  const mixedHeaders = "content-type: application/json\nserver: nginx\r\ncache-control: no-cache\ncontent-length: 1234";

  // 测试用例5: 空字符串
  // const emptyHeaders = "";

  // 测试用例6: 很长的响应头(性能压力测试)
  const longHeaders = Array(100)
    .fill(0)
    .map((_, i) => `x-custom-header-${i}:   value-${i}`)
    .join("\r\n");

  let atomicId = 10_000_000;
  bench("简单响应头-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${simpleHeaders}`);
  });

  bench("包含多余空格的响应头-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${headersWithSpaces}`);
  });

  bench("复杂真实场景响应头-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${complexHeaders}`);
  });

  bench("混合分隔符响应头-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${mixedHeaders}`);
  });

  bench("长响应头 (100个header)-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${longHeaders}`);
  });

  bench("简单响应头-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${simpleHeaders}`);
  });

  bench("包含多余空格的响应头-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${headersWithSpaces}`);
  });

  bench("复杂真实场景响应头-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${complexHeaders}`);
  });

  bench("混合分隔符响应头-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${mixedHeaders}`);
  });

  bench("长响应头 (100个header)-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${longHeaders}`);
  });
});

Copy link
Member

@CodFrm CodFrm Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果不处理 \r 的话,我也修改了并通过了单元测试,某些情况会好一点点,差距极小,但是这点差距有什么意义呢,你为什么如此的排斥语法糖,JS本来就是一个解释型的语言,他不像编译型的语言,一些操作可以直接访问内存会更快,一些语法糖V8有内部的优化,你以为的一些优化可能并没有效果,反而会加重解释器的负担

我可能说服不了你,但是我不想再因为这些舍弃可读性和架构整洁了,除了你、我可能还会有其他人来阅读,水平不够或者不了解的人只会两眼一黑,为了读懂这代码所消耗的能量已经够SC所有用户跑上几十年了:

 ✓ src/pkg/utils/utils.bench.ts > nativeResponseHeadersTreatment 基准测试 9305ms
     name                           hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · 简单响应头-1              3,101,845.11  0.0001  8.3151  0.0003  0.0002  0.0005  0.0006  0.0050  ±5.48%  1550923
   · 包含多余空格的响应头-1         3,232,974.52  0.0002  1.2363  0.0003  0.0003  0.0003  0.0007  0.0010  ±2.81%  1616488
   · 复杂真实场景响应头-1            865,962.22  0.0008  2.8180  0.0012  0.0010  0.0016  0.0024  0.0175  ±3.14%   433564
   · 混合分隔符响应头-1           2,533,276.00  0.0002  3.1258  0.0004  0.0003  0.0004  0.0008  0.0012  ±3.56%  1266688
   · 长响应头 (100个header)-1    137,587.81  0.0064  0.5487  0.0073  0.0068  0.0083  0.0169  0.2648  ±1.18%    68794
   · 简单响应头-2              2,703,374.50  0.0002  2.3180  0.0004  0.0003  0.0004  0.0008  0.0012  ±3.77%  1351688
   · 包含多余空格的响应头-2         2,371,600.25  0.0003  1.9080  0.0004  0.0004  0.0005  0.0008  0.0011  ±2.96%  1185801
   · 复杂真实场景响应头-2            914,793.00  0.0008  0.8549  0.0011  0.0010  0.0014  0.0016  0.0045  ±2.37%   457397
   · 混合分隔符响应头-2           2,450,759.48  0.0003  0.6513  0.0004  0.0004  0.0005  0.0005  0.0011  ±0.30%  1225380
   · 长响应头 (100个header)-2    140,328.80  0.0062  0.6886  0.0071  0.0066  0.0083  0.0157  0.2791  ±1.28%    70165

 BENCH  Summary

  包含多余空格的响应头-1 - src/pkg/utils/utils.bench.ts > nativeResponseHeadersTreatment 基准测试
    1.04x faster than 简单响应头-1
    1.20x faster than 简单响应头-2
    1.28x faster than 混合分隔符响应头-1
    1.32x faster than 混合分隔符响应头-2
    1.36x faster than 包含多余空格的响应头-2
    3.53x faster than 复杂真实场景响应头-2
    3.73x faster than 复杂真实场景响应头-1
    23.04x faster than 长响应头 (100个header)-2
    23.50x faster than 长响应头 (100个header)-1
import { bench, describe } from "vitest";

// TM Xhr Header 兼容处理,原生xhr \r\n 在尾,但TM的GMXhr没有;同时除去冒号后面的空白
export const nativeResponseHeadersTreatment1 = (hs: string) => {
  let start = 0;
  let out = "";
  const len = hs.length;
  let separator = "";
  while (start < len) {
    const i = hs.indexOf(":", start); // 冒号的位置
    let j = hs.indexOf("\n", start); // 换行符的位置
    if (j < 0) j = len; // 尾行
    if (i < j) {
      const key = hs.substring(start, i).trim(); // i 为 -1 的话 key 也会是空值
      if (key) {
        out += `${separator}${key}:${hs.substring(i + 1, j).trim()}`;
        separator = "\r\n";
      }
    }
    start = j + 1; // 移到下一行
  }
  return out;
};

export const nativeResponseHeadersTreatment2 = (headersString: string) => {
  if (!headersString) return "";
  let out = "";
  headersString.split("\n").forEach((line) => {
    const j = line.indexOf(":");
    if (j > 0) {
      const headerName = line.substring(0, j); // "key"
      const headerValue = line.substring(j + 1).trim(); // "value"
      out += `${headerName}:${headerValue}\r\n`;
    }
  });
  return out.substring(0, out.length - 2); // 去掉最后的 \r\n
};

describe("nativeResponseHeadersTreatment 基准测试", () => {
  // 测试用例1: 简单的响应头
  const simpleHeaders = "content-type: application/json\r\nserver: nginx";

  // 测试用例2: 包含多余空格的响应头
  const headersWithSpaces = "content-type:    application/json\r\nserver:   nginx\r\ncache-control:  no-cache";

  // 测试用例3: 复杂的响应头(真实场景)
  const complexHeaders = `content-type: text/html; charset=utf-8\r\n
server: Apache/2.4.41 (Ubuntu)\r\n
set-cookie: sessionid=abc123; Path=/; HttpOnly\r\n
cache-control: no-store, no-cache, must-revalidate\r\n
expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n
pragma: no-cache\r\n
x-frame-options: SAMEORIGIN\r\n
x-content-type-options: nosniff\r\n
content-security-policy: default-src 'self'\r\n
access-control-allow-origin: *`;

  // 测试用例4: 包含多种分隔符的响应头(混合 \r\n 和 \n)
  const mixedHeaders = "content-type: application/json\nserver: nginx\r\ncache-control: no-cache\ncontent-length: 1234";

  // 测试用例5: 空字符串
  // const emptyHeaders = "";

  // 测试用例6: 很长的响应头(性能压力测试)
  const longHeaders = Array(100)
    .fill(0)
    .map((_, i) => `x-custom-header-${i}:   value-${i}`)
    .join("\r\n");

  let atomicId = 10_000_000;
  bench("简单响应头-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${simpleHeaders}`);
  });

  bench("包含多余空格的响应头-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${headersWithSpaces}`);
  });

  bench("复杂真实场景响应头-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${complexHeaders}`);
  });

  bench("混合分隔符响应头-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${mixedHeaders}`);
  });

  bench("长响应头 (100个header)-1", () => {
    nativeResponseHeadersTreatment1(`${++atomicId}${longHeaders}`);
  });

  bench("简单响应头-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${simpleHeaders}`);
  });

  bench("包含多余空格的响应头-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${headersWithSpaces}`);
  });

  bench("复杂真实场景响应头-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${complexHeaders}`);
  });

  bench("混合分隔符响应头-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${mixedHeaders}`);
  });

  bench("长响应头 (100个header)-2", () => {
    nativeResponseHeadersTreatment2(`${++atomicId}${longHeaders}`);
  });
});

Copy link
Collaborator Author

@cyfung1031 cyfung1031 Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修改后的 nativeResponseHeadersTreatment1 已经是很好读的吧
就是简单的一行一行处理
你要用 nativeResponseHeadersTreatment2 我也没意见

你觉得 headersString.split("\n").forEach((line) => { ... } 是好一点阅读也可以呀
我没所谓


操作多,日后不预期大改动,PR的写法都尽量平衡阅读和效能
这个东西写了之后就永远不用改动。
也不是几页纸的长度
这20行写的是很一般的程序
里面又没有什么复杂 algorithm

我觉得是观点角度问题啦。我认为 7a2dbe6 这个修改已经是相关简化
不过你不欣赏对字串用这种看似C代码的写法,也是一种看法

像一个没写开 React 的人,看到 React 都会完全看不懂一样
每个人的看法不一样吧

在我看起来,现在只用了 indexOf, while 等东西,是一个简单合理的写法
你不喜欢也行呀,改成你的 split("\n") 吧
当然这不是重大的效能影响
但 12 行 跟 20 行 的代码,我看起来不懂的人还是不懂,懂的人还是懂

Copy link
Member

@CodFrm CodFrm Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

相比之前确实好一些,但是依旧没有 nativeResponseHeadersTreatment2 的直接,这里的主要目的还是希望你不要那么排斥语法糖,性能并没有那么差

那我修改为 nativeResponseHeadersTreatment2 了

@CodFrm CodFrm merged commit 15232c8 into scriptscat:main Dec 17, 2025
3 checks passed
}
return out;
});
return out.substring(0, out.length - 2); // 去掉最后的 \r\n
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

注:这段可以用 ${separator}${headerName}:${headerValue} 这样来避免最后呼叫 substring
不过作者认为这些是过度优化那就算了

cyfung1031 added a commit to cyfung1031/scriptcat that referenced this pull request Dec 19, 2025
* responseHeaders: `TM兼容: 使用 \r\n 及不包含空白`

Co-Authored-By: wangyizhi <yz@ggnb.top>

* 中文

* 代码调整

* added streamReader error

* 代码调整

* 代码调整

* 加注释

* nativeResponseHeadersTreatment -> normalizeResponseHeaders

* Update bg_gm_xhr.ts

* update

* 代码调整

* 代码调整

* 单元测试

* 修改 normalizeResponseHeaders 实现

---------

Co-Authored-By: wangyizhi <yz@ggnb.top>
@cyfung1031 cyfung1031 deleted the fix_1078_3 branch December 21, 2025 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hotfix 需要尽快更新到扩展商店 P0 🚑 需要紧急处理的内容

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants