在 Chrome 扩展 (V3) 中使用 fetch() 时,使用 declarativeNetRequest 设置“Referer”标头

som*_*nus 0 google-chrome-extension django-rest-framework fetch-api

我正在使用清单 V3 开发 chrome 扩展。该扩展的核心功能是使用户能够将数据从网站发送到我的 django 应用程序的 REST API,其中用户已经登录。在本地测试时一切都很好,但是当我去登台测试时,我发现使用 HTTPS django 需要在 POST 标头中使用“referer”来进行 CSRF 保护。

据我发现,chrome 扩展只是不附加该标头。所以我declarativeNetRequest使用以下代码尝试了 API。然而,这仅当我在选项卡中打开 URL 时才有效。当调用 fetch 来发布到相同的 URL 时,规则不匹配。这是在 V3 中使用 fetch 时强制引用标头的正确方法吗?谢谢!

清单.json:

...

"permissions": [
    ...
    "declarativeNetRequestWithHostAccess",
    "declarativeNetRequestFeedback"
  ],
  "declarative_net_request": {
    "rule_resources": [{
      "id": "ruleset_1",
      "enabled": true,
      "path": "rules.json"
    }]
  },

...
Run Code Online (Sandbox Code Playgroud)

规则.json:

[
  {
    "id": 1,
    "priority": 1,
    "action": {
      "type": "modifyHeaders",
      "requestHeaders": [
        {
          "header": "Referer",
          "operation": "set",
          "value": "whatever"
        }
      ]
    },
    "condition": {
      "urlFilter": "https://api.myserver.com",
      "resourceTypes": [
        "main_frame"
      ]
    }
  }
]
Run Code Online (Sandbox Code Playgroud)

背景.js:

...

chrome.declarativeNetRequest.onRuleMatchedDebug.addListener(function (m) {
  console.log('match:', m);
});

function post_data() {
    fetch(link, {
        method: 'POST',
        headers: {
            'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
            'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
            'X-CSRFToken': csrf_token.value
        },
        body: JSON.stringify(text)
    })
        .then(response => console.log(response))
        .catch(error => console.log('Error:', error))

    return true;
}

...
Run Code Online (Sandbox Code Playgroud)

wOx*_*xOm 9

您需要替换main_framexmlhttprequest,它是 XHR 和 的类型fetch

另外,请将此规则限制为您的分机发出的请求。可以通过在 中指定扩展的 id 来完成domains。由于 id 在开发过程中可能会发生变化,因此我们将动态设置规则。

  1. 从manifest.json 中删除declarative_net_request
  2. 在background.js中添加以下代码:
chrome.runtime.onInstalled.addListener(async () => {
  const rules = [{
    id: 1,
    action: {
      type: 'modifyHeaders',
      requestHeaders: [{
        header: 'Referer',
        operation: 'set',
        value: 'whatever',
      }],
    },
    condition: {
      domains: [chrome.runtime.id],
      urlFilter: '|https://api.myserver.com/',
      resourceTypes: ['xmlhttprequest'],
    },
  }];
  await chrome.declarativeNetRequest.updateDynamicRules({
    removeRuleIds: rules.map(r => r.id),
    addRules: rules,
  });
});
Run Code Online (Sandbox Code Playgroud)