首页
/ Electron Referrer 对象详解:用 url 与 policy 字段精确控制 Referer 行为

Electron Referrer 对象详解:用 url 与 policy 字段精确控制 Referer 行为

2026-09-06 15:24:17作者:劳婵绚Shirley

本文基于 Electron 官方 API 文档中的 Referrer Object 结构定义,系统讲解该对象的 urlpolicy 两个字段,逐一解释 8 种 Referrer-Policy 取值的含义,并结合 Electron C++ 源码中的字符串到 net::ReferrerPolicy 枚举的映射实现、loadURLhttpReferrer 参数解析链路,帮助你在主进程、<webview>net 请求等场景中精确控制请求的 Referer 头。

什么是 Referrer 对象

Referrer 是 Electron API 中的一个数据结构(structure),而不是可直接实例化的类。它成对描述一次导航或请求所使用的 HTTP Referrer(即浏览器侧的 Referer 请求头来源):

  • url string — HTTP Referrer URL,即作为来源页的完整 URL;
  • policy string — Referrer-Policy 策略值,决定 url 在跨源、降级(如 https 请求 http)等场景下以何种粒度(完整 URL / 仅源 / 不发送)出现在 Referer 请求头中。

policy 的合法取值为:defaultunsafe-urlno-referrer-when-downgradeno-referreroriginstrict-origin-when-cross-originsame-originstrict-origin

与纯字符串形式的 referrer 相比,Referrer 对象的关键价值在于:它把"来源 URL"和"发送策略"绑定在一起。只传一个 URL 字符串时,策略只能走默认值;而传入 Referrer 对象后,Electron 会按你指定的策略在每次真实发出 Referer 头之前做裁剪。

8 种 policy 取值含义速查

取值 行为摘要
default 使用默认策略(不额外裁剪)
unsafe-url 始终发送完整 URL,即使从 https 降级到 http 也照常发送
no-referrer-when-downgrade 同源或 httpshttps 时发送完整 URL;降级时不发送
no-referrer 永不发送 Referer
origin 只发送来源的源(scheme + host + port),不发送路径
strict-origin-when-cross-origin 同源请求发送完整 URL;跨源只发送源;降级请求不发送
same-origin 仅同源请求发送完整 URL,跨源不发送
strict-origin 只发送源,且仅在安全上下文(如 httpshttps)下发送

其中"降级"(downgrade)指从安全协议(https)转向非安全协议(http)的导航,这也是多数 strict-* / no-referrer-when-downgrade 策略的核心判断条件。

源码实现:JS 字符串到 net::ReferrerPolicy 的映射

Electron 在 V8 与 Chromium 网络栈之间通过 gin 的 Converter 完成字符串到枚举的转换。在 electron_api_url_loader.cc 中可以看到完整的映射表:

template <>
struct Converter<net::ReferrerPolicy> {
  static bool FromV8(v8::Isolate* isolate,
                     v8::Local<v8::Value> val,
                     net::ReferrerPolicy* out) {
    using Val = net::ReferrerPolicy;
    static constexpr auto Lookup =
        base::MakeFixedFlatMap<std::string_view, Val>({
            {"", Val::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN},
            {"no-referrer", Val::NO_REFERRER},
            {"no-referrer-when-downgrade", Val::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE},
            {"origin", Val::ORIGIN},
            {"origin-when-cross-origin", Val::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN},
            {"same-origin", Val::CLEAR_ON_TRANSITION_CROSS_ORIGIN},
            {"strict-origin", Val::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE},
            {"strict-origin-when-cross-origin", Val::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN},
            {"unsafe-url", Val::NEVER_CLEAR},
        });
    return FromV8WithLowerLookup(isolate, val, Lookup, out);
  }
};

从这段实现可以得到几个与文档对照后值得注意的事实:

  1. strict-origin-when-cross-origin 与空字符串 "" 映射到同一枚举 REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN。也就是说 Chromium 的默认策略等价于 strict-origin-when-cross-origin,文档中列出的 default 语义在实现层面落到这一默认值上。
  2. 映射表额外接受 origin-when-cross-origin,即源码侧支持的策略字符串比 Referrer 文档 列出的 8 个还多一个;文档中的 8 个取值是面向 Referrer 结构 policy 字段的正式声明。
  3. FromV8WithLowerLookup 表明匹配是大小写不敏感的,传入 NO-REFERRER 这类写法同样可以生效。
  4. 枚举命名本身也直观体现了策略语义:NEVER_CLEAR(永不裁剪,对应 unsafe-url)、CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE(降级时清空,对应 no-referrer-when-downgrade)、ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN 等。

另外,electron_api_url_loader.ccfetch 式请求的默认策略为 blink::ReferrerUtils::GetDefaultNetReferrerPolicy(),并支持从 referrerPolicy 选项覆盖;而 system_network_context_manager.ccenable_referrers = true 说明 Electron 的系统网络上下文是开启 referrer 支持的,策略裁剪才真正有意义。

实战场景一:loadURL 的 httpReferrer 参数

Referrer 对象最常见的入口是 loadURLoptions.httpReferrer,其类型为 string | Referrer。文档中以下位置均如此声明:

  • webContents.loadURLhttpReferrer (string | Referrer) (optional) - An HTTP Referrer url.);
  • win.loadURL<webview>.loadURLwebview-tag.md),参数列表与 webContents.loadURL 一致(httpReferreruserAgentextraHeaderspostDatabaseURLForDataURL)。

electron_api_web_contents.cc 中可以看到两种入参的处理差异:

content::NavigationController::LoadURLParams params(url);

if (!options.Get("httpReferrer", &params.referrer)) {
  GURL http_referrer;
  if (options.Get("httpReferrer", &http_referrer))
    params.referrer =
        content::Referrer(http_referrer.GetAsReferrer(),
                          network::mojom::ReferrerPolicy::kDefault);
}
  • 传入 Referrer 对象:直接反序列化为 content::Referrer,你指定的 policy 会一路带到导航请求;
  • 传入字符串:先用 GURL 解析,再包装为 content::Referrer(url, ReferrerPolicy::kDefault),即策略固定为默认值。

因此,当你需要控制"来源页是 A 但只暴露 origin"这类行为时,必须传对象而不是字符串

mainWindow.loadURL('https://example.com/target', {
  httpReferrer: {
    url: 'https://mysite.com/checkout',
    policy: 'origin'  // 跨源时只发送 https://mysite.com
  }
})

仓库的 TypeScript 冒烟测试 main.ts 也验证了 loadURL 接受 httpReferrer 选项的类型签名:

mainWindow.loadURL('file://foo/bar', { userAgent: 'cool-agent', httpReferrer: 'greatReferrer' });
mainWindow.webContents.loadURL('file://foo/bar', { userAgent: 'cool-agent', httpReferrer: 'greatReferrer' });

实战场景二:did-create-window 事件中读取 referrer

当页面调用 window.open() 时,webContentsdid-create-window 事件的 details 中带有 referrer 字段,其类型正是 Referrer 对象:

referrer Referrer - The referrer that will be passed to the new window. May or may not result in the Referer header being sent, depending on the referrer policy.

文档特别强调:是否真的产生 Referer 头,取决于其中的 policy——这正是把 urlpolicy 放一起表达的原因。典型用法是在自定义 setWindowOpenHandler / 监听 did-create-window 时,根据来源页 URL 与策略做白名单校验:

mainWindow.webContents.on('did-create-window', (childWindow, details) => {
  const { url, policy } = details.referrer
  console.log(`opened from ${url} with policy ${policy}`)
  // 例如:只有 policy 为 'no-referrer' 的来源才允许打开外链
})

实战场景三:context-menu 事件的 referrerPolicy 字段

webContents<webview>context-menu 事件参数中也带有 referrerPolicy 字段(类型同为 Referrer 结构,见 web-contents.mdwebview-tag.md 的 context-menu 参数列表):

referrerPolicy Referrer - The referrer policy of the frame on which the menu is invoked.

它反映的是右键所在 frame 当前生效的 referrer 策略。当你自定义右键菜单、需要"在新窗口打开链接"等功能时,可以读取该字段判断当前页面的策略环境,再决定后续导航携带怎样的 referrer。

周边 API 中的 referrer 支持

Referrer 对象之外,Electron 还有几处相关能力,可对照理解策略的实际作用点:

  1. net.request 的 referrerPolicynet 模块发起的请求支持 referrerreferrerPolicy 选项。electron_api_url_loader.ccopts.Get("referrerPolicy", &request->referrer_policy) 完成解析,且默认值为 GetDefaultNetReferrerPolicy()。集成测试 api-net-spec.ts 验证了这一点:

    // The referrerPolicy must be unsafe-url because the referrer's origin
    // is http:// while the request url is https://
    const urlRequest = net.request({ url: serverUrl, referrerPolicy: 'unsafe-url' });
    

    该测试用例正好演示了策略裁剪的实际影响:若 referrer 是 http:// 而目标为 https://,默认策略下 Referer 会被清空,必须显式指定 unsafe-url 才能发出完整 URL。

  2. webRequest 的 details.referrerelectron_api_web_request.ccdetails->Set("referrer", request.referrer) 将 referrer 注入 onBeforeRequest 等事件的 details(字符串形式)。因此你可以用 session.defaultSession.webRequest 在请求管线中观测或改写请求头,但注意 details.referrer 本身是只读的字符串字段,要影响最终发出的 Referer,应通过 onBeforeSendHeaders 修改 requestHeaders(见 web-request.md)。

  3. net 重定向链路electron_url_loader_factory.cc 在重定向时同步更新 request_.referrerrequest_.referrer_policy,说明策略跟随重定向后的新 referrer 生效,与 Referrer-Policy 规范的语义一致。

小结

  • Referrer 对象由 url(来源 URL)与 policy(8 种取值之一的策略)组成,是 Electron 中表达"带策略的 Referer"的标准数据结构;
  • 策略字符串在 electron_api_url_loader.ccConverter<net::ReferrerPolicy> 中完成到 Chromium 枚举的映射,匹配大小写不敏感,且源码侧额外支持 origin-when-cross-origin
  • 需要自定义策略时,loadURL 必须传 Referrer 对象而非字符串,否则策略会被固定为 kDefault
  • did-create-windowdetails.referrercontext-menureferrerPolicynet.requestreferrerPolicywebRequestdetails.referrer 构成了完整的观测与介入面,可结合 net.mdweb-request.md 的文档进一步使用。
登录后查看全文
热门项目推荐
相关项目推荐