declarativeNetRequest: Redirect POST to GET of extensionPath causes net::ERR_UNSAFE_REDIRECT

229 views
Skip to first unread message

Matt Kruse

unread,
Feb 11, 2024, 11:54:07 AM2/11/24
to Chromium Extensions
I have created an extension for a production app, that intercepts fetch calls to serve static json responses for demo purposes.
Problem: For POST requests, the browser does not like me to redirect to a GET of a local extension path, like this:
action: {
type: 'redirect',
redirect: {
extensionPath: '/data/response.json'
}
}
In the browser console, I see net::ERR_UNSAFE_REDIRECT
Everything works great for GET requests.
Is there anything I can do to mock json responses to POST fetch calls, using local extension data?

From what I understand, declarativeNetRequest redirects get converted to GET by default, but I'm wondering if the redirect is a 307 which tries to maintain the POST body? (which I don't care about, since I am mocking the response).

wOxxOm

unread,
Feb 11, 2024, 1:48:59 PM2/11/24
to Chromium Extensions, Matt Kruse
Sounds like a bug. Try redirecting to "url": "data:application/json,........."

Matt Kruse

unread,
Feb 11, 2024, 3:56:46 PM2/11/24
to Chromium Extensions, wOxxOm, Matt Kruse
My json responses are stored as files in the extension. How would I go about converting them to data:application urls? The convenience for me is that I have many json responses to mock, and having them each in .json files is very convenient for editing and replacing.

Also, I have confirmed that the extension is returning a 307, which in this case is inappropriate. It should return a 303, I believe. This will force a GET and not cause an issue. Whenever extensionPath is used in a redirect, I believe it should be 303.

wOxxOm

unread,
Feb 11, 2024, 3:58:59 PM2/11/24
to Chromium Extensions, Matt Kruse, wOxxOm
fetch() the file contents as blob(), then use FileReader + readAsDataURL()
Alternatively, you can inline the contents in a string as a build step in webpack.

Matt Kruse

unread,
Feb 11, 2024, 4:01:04 PM2/11/24
to Chromium Extensions, wOxxOm, Matt Kruse
With declarativeNetRequest I don't think there is any way to do run-time execution, is there? So I would need to do this in advance, at build time like you mentioned.
The problem comes with very large json responses which would exceed url limits. I'll have to see if this is an issue.
Good idea, though. I had not considered this.

wOxxOm

unread,
Feb 11, 2024, 4:02:00 PM2/11/24
to Chromium Extensions, Matt Kruse, wOxxOm
Use chrome.declarativeNetRequest.updateDynamicRules

Matt Kruse

unread,
Feb 11, 2024, 4:13:12 PM2/11/24
to Chromium Extensions, wOxxOm, Matt Kruse
I'm already using that to dynamically inject all my rules, but it still doesn't give you a hook to execute code at request-time.
I'm going to try build-time and see what limitations I hit.

wOxxOm

unread,
Feb 11, 2024, 4:15:19 PM2/11/24
to Chromium Extensions, Matt Kruse, wOxxOm
There's no need for a callback. In chrome.runtime.onInstalled you read the files, encode as data urls, and call chrome.declarativeNetRequest.updateDynamicRules.

Matt Kruse

unread,
Feb 11, 2024, 5:13:33 PM2/11/24
to Chromium Extensions, wOxxOm, Matt Kruse
My concern is that the redirect will still be a 307 and the browser will still throw an exception if I try to POST to a data: URL. Unfortunately I can't test it for a bit, do you happen to know if chrome will complain?

wOxxOm

unread,
Feb 11, 2024, 5:30:54 PM2/11/24
to Chromium Extensions, Matt Kruse, wOxxOm
I don't know.

BTW, there's need for FileReader and base64 encoding as it's not efficient. A better one is UTF8 + escaping:
'data:application/json,' + fileText.replaceAll('#', '%23')

wOxxOm

unread,
Feb 11, 2024, 5:31:53 PM2/11/24
to Chromium Extensions, wOxxOm, Matt Kruse
Ah, and maybe use JSON.stringify(JSON.parse(text)) to trim the spaces.

Matt Kruse

unread,
Feb 11, 2024, 6:21:49 PM2/11/24
to Chromium Extensions, wOxxOm, Matt Kruse
No luck. A redirect to a data: url from a POST request still fails in the browser. :( 

Matt Kruse

unread,
Feb 12, 2024, 8:32:23 AM2/12/24
to Chromium Extensions, Matt Kruse, wOxxOm
I'm adding a content script to my extension that monkey-patches fetch to force all API calls to be GET.
This works, but I hate it :) 

Reply all
Reply to author
Forward
0 new messages