Chrome扩展转发Instagram请求至本地脚本遇CSP错误求助
开发一款仅供个人使用的Chrome扩展,需求是监控所有发往https://www.instagram.com/api/graphql的请求,并将响应转发至本地部署在localhost的脚本。目前已成功捕获响应并能通过console.log打印,但因Content Security Policy(CSP)限制,无法将数据转发到目标脚本。
代码实现
manifest.json
{ "manifest_version": 3, "name": "BytE IG", "description": "BytE Instagram checker", "version": "1.3", "content_security_policy": { "extension_pages": "script-src 'self' http://localhost; object-src 'self' script-src-elem 'self'" }, "background": { "service_worker": "background.js" }, "host_permissions": [ "*://*/*" ], "permissions": [ "activeTab", "tabs", "webRequest" ], "content_scripts": [ { "matches": ["*://*.instagram.com/direct/*"], "run_at": "document_start", "js": ["inject.js"] } ], "web_accessible_resources": [ { "resources": ["injected.js"], "matches": ["*://*.instagram.com/*"] } ] }
background.js
chrome.webRequest.onCompleted.addListener( (details) => { const url = new URL(details.url); console.log('caught request' + url); }, { urls: "https://*.instagram.com/api/graphql*" } );
inject.js
var s = document.createElement('script'); s.src = chrome.runtime.getURL('injected.js'); s.onload = function() { this.remove(); }; (document.head || document.documentElement).appendChild(s);
injected.js
(function(xhr) { var XHR = XMLHttpRequest.prototype; var open = XHR.open; var send = XHR.send; var setRequestHeader = XHR.setRequestHeader; XHR.open = function(method, url) { this._method = method; this._url = url; this._requestHeaders = {}; this._startTime = (new Date()).toISOString(); return open.apply(this, arguments); }; XHR.setRequestHeader = function(header, value) { this._requestHeaders[header] = value; return setRequestHeader.apply(this, arguments); }; XHR.send = function(postData) { this.addEventListener('load', function() { var endTime = (new Date()).toISOString(); var myUrl = this._url ? this._url.toLowerCase() : this._url; if(myUrl) { if (postData) { if (typeof postData === 'string') { try { this._requestHeaders = postData; } catch(err) { console.log('Request Header JSON decode failed, transfer_encoding field could be base64'); console.log(err); } } } var responseHeaders = this.getAllResponseHeaders(); if ( this.responseType != 'blob' && this.responseText) { try { var arr = this.responseText; var data = new URLSearchParams(); data.set('ig', arr); fetch("http://localhost:1608/ig.php", { method: 'POST', mode: 'no-cors', cache: 'no-cache', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: data }).then(function(response) { // check the response object for result }); } catch(err) { console.log("Error in responseType try catch"); console.log(err); } } } }); return send.apply(this, arguments); }; })(XMLHttpRequest);
错误信息
injected.js:62 Refused to connect to 'http://localhost:1608/ig.php' because it violates the document's Content Security Policy.
(anonymous) @ injected.js:62
injected.js:62 Refused to connect to 'http://localhost:1608/ig.php' because it violates the document's Content Security Policy.
(anonymous) @ injected.js:62
injected.js:62 Refused to connect to 'http://localhost:1608/ig.php' because it violates the document's Content Security Policy.
(anonymous) @ injected.js:62
injected.js:62 Refused to connect to 'http://localhost:1608/ig.php' because it violates the document's Content Security Policy.
(anonymous) @ injected.js:62
injected.js:62 Refused to connect to 'http://localhost:1608/ig.php' because it violates the document's Content Security Policy.
补充说明
已尝试使用带SSL证书的完全限定域名(FQDN)替代localhost,问题依旧。
内容的提问来源于stack exchange,提问作者byteflush

