You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MV3 declarativeNetRequest无法绕过X-Frame-Options DENY问题求助

解决MV3扩展中declarativeNetRequest无法绕过X-Frame-Options DENY的问题

问题根源分析

在多信使扩展场景中,需在example.com(或扩展内部页面)嵌入Twitter、Telegram等站点的iframe,但这些站点设置了X-Frame-Options: DENY及CSP限制,同时Cookie的SameSite属性会阻止跨域会话。MV2中通过chrome.webRequest移除限制头并修改Cookie SameSite可正常解决,但迁移到MV3后两种尝试方案均失效,核心问题如下:

第一种方案的缺陷

  1. 规则更新逻辑错误:调用updateSessionRules时同时执行removeRuleIds: [id],但该ID的规则尚未创建,导致整个规则更新操作失败
  2. Cookie修改方式错误:使用set操作覆盖整个Set-Cookie值,破坏原有会话数据,与MV2中仅修改SameSite属性的逻辑不符
  3. 优先级不足:规则优先级设为1,可能被浏览器默认规则覆盖
  4. CSP处理不完整:仅移除了单独的frame-ancestors头,未处理包含该指令的Content-Security-Policy头

第二种方案的缺陷

  1. 限制处理不全面:仅移除X-Frame-Options,未处理CSP的frame-ancestors限制
  2. Cookie问题未解决:未修改Cookie的SameSite属性,导致嵌入页面无法正常携带会话Cookie
  3. 发起域名匹配错误:若嵌入容器是扩展内部页面,initiatorDomains: ['example.com']不匹配,需改为扩展ID对应的域名

修复方案

1. 权限确认

确保manifest.json中已配置正确权限(现有配置已满足,但需验证):

"permissions": [
  "storage",
  "declarativeNetRequestWithHostAccess",
  // 其他必要权限...
],
"host_permissions": ["<all_urls>"]

2. 修正Session规则实现(替代第一种方案)

修复规则更新逻辑,采用modify操作精准修改Cookie SameSite属性,移除所有iframe限制头:

async function NetRequest() {
  const targetDomains = ["*://*.twitter.com/*", "*://*.telegram.org/*"];
  const tabId = await getObjectFromLocalStorage('tabId');
  let tabMultiId = JSON.parse(await getObjectFromLocalStorage('tabMultiId')) || [];
  tabMultiId.push(tabId);

  // 批量生成规则
  const newRules = targetDomains.map((domain, idx) => ({
    id: idx + 1,
    priority: 1000, // 提高优先级确保规则优先生效
    action: {
      type: "modifyHeaders",
      responseHeaders: [
        // 移除iframe限制相关头
        { header: "X-Frame-Options", operation: "remove" },
        { header: "Content-Security-Policy", operation: "remove" },
        { header: "X-Content-Security-Policy", operation: "remove" },
        { header: "Strict-Transport-Security", operation: "remove" },
        // 修改SameSite=Strict/Lax为SameSite=None
        {
          header: "Set-Cookie",
          operation: "modify",
          regexReplace: "(SameSite=Strict|SameSite=Lax)",
          replaceWith: "SameSite=None"
        },
        // 为仅含Secure的Cookie添加SameSite=None
        {
          header: "Set-Cookie",
          operation: "modify",
          regexReplace: "(; Secure)(?!.*SameSite=None)",
          replaceWith: "; SameSite=None; Secure"
        }
      ]
    },
    condition: {
      urlFilter: domain,
      resourceTypes: ["sub_frame", "main_frame", "xmlhttprequest"], // 仅包含必要资源类型
      tabIds: tabMultiId
    }
  }));

  // 先移除旧规则,再添加新规则
  const oldRuleIds = newRules.map(r => r.id);
  await chrome.declarativeNetRequest.updateSessionRules({
    removeRuleIds: oldRuleIds,
    addRules: newRules
  });
}

async function launchWindow(newURL, windowDimensions, urlWindow, isIncognitoWindow, windowType) {
  chrome.windows.create({ 
    url: newURL, 
    type: windowType, 
    incognito: isIncognitoWindow, 
    width: windowDimensions.width, 
    height: windowDimensions.height, 
    left: windowDimensions.left, 
    top: windowDimensions.top 
  }, async (chromeWindow) => {
    // 修正逻辑错误:原||会导致条件永远为true
    if (urlWindow !== "install" && urlWindow !== "update") {
      await chrome.storage.local.set({ 
        extensionWindowId: chromeWindow.id,
        tabId: chromeWindow.tabs[0].id 
      });
      await NetRequest();
    }
  });
}

3. 修复固定域名嵌入方案(第二种方案优化)

若嵌入容器是example.com外部页面,调整规则覆盖所有限制并处理Cookie:

const iframeHosts = ['twitter.com', 'telegram.org'];
const RULE_ID = 1;

const embedRule = {
  id: RULE_ID,
  priority: 1000,
  condition: {
    initiatorDomains: ['example.com'],
    requestDomains: iframeHosts,
    resourceTypes: ['sub_frame', 'main_frame'],
  },
  action: {
    type: 'modifyHeaders',
    responseHeaders: [
      { header: 'X-Frame-Options', operation: 'remove' },
      { header: 'Content-Security-Policy', operation: 'remove' },
      // 修改Cookie SameSite属性
      {
        header: 'Set-Cookie',
        operation: 'modify',
        regexReplace: "(SameSite=Strict|SameSite=Lax)",
        replaceWith: "SameSite=None"
      },
      {
        header: 'Set-Cookie',
        operation: 'modify',
        regexReplace: "(; Secure)(?!.*SameSite=None)",
        replaceWith: "; SameSite=None; Secure"
      }
    ],
  },
};

// 更新动态规则
chrome.declarativeNetRequest.updateDynamicRules({
  removeRuleIds: [RULE_ID],
  addRules: [embedRule],
});

关键注意事项

  • 优先级设置:必须将规则优先级设为较高值(如1000),确保优先于浏览器或其他扩展的规则
  • Cookie修改方式:务必使用modify+regexReplace操作,避免用set覆盖原有Cookie数据
  • 资源类型筛选:仅包含必要的resourceTypes,减少不必要的性能开销
  • 扩展页面适配:若嵌入容器是扩展内部页面,需将initiatorDomains改为["chrome-extension://<你的扩展ID>"],或通过requestInitiator的urlFilter匹配扩展URL

内容的提问来源于stack exchange,提问作者user1327579

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 05:05:14