Open dsanders11 opened 5 years ago
YES!! Would LOVE to have this functionality!
Just to add to this, I've been using Puppeteer for my functional tests and it has the following:
await page.setRequestInterception(true);
page.on('request', interceptedRequest => {
if (interceptedRequest.url().endsWith('.png') || interceptedRequest.url().endsWith('.jpg'))
interceptedRequest.abort();
else
interceptedRequest.continue();
});
So theoretically it should be possible to lift and shift some of the necessary code to achieve this behaviour.
Fwiw, this has precedent and the CEFSharp API provides an API to intercept specific URLs and not the scheme wholesale: https://github.com/cefsharp/CefSharp/wiki/General-Usage#loading-htmlcssjavascriptetc-from-diskdatabaseembedded-resourcestream
Any updates on this being implemented?
Is there any alternative for modifying requests?
Not sure if I am reading this correctly, but to me it seems like that this is a chrome functionality they are just wrapping on electrons side of things. If this is true, this might not change it if chrome doesn't change it.
I would love to be wrong about this, though. Having an alternative to either run a local web server or to serve from the file protocol would be great, as both approaches causing all sorts of issues (service workers, third party authentication flows, not being able to occupy the same local port,etc).
Any news?
This would really be extremely helpful. The current webRequest.onBeforeXXX doesn't really allow you to handle all the cases and from the documentation it isn't clear at all how you could intercept only SOME requests, while letting all others handle normally.
Almost two years, No reponse
This is not the same of what the OP requested, but an alternative is passing an array of URL patterns as second argument to intercept{Any}Protocol
which limits the callback to intercept only URLs that match the patterns. Here's a patch to anyone interested: https://gist.github.com/tarruda/554962f987f7f3a1a94d2c1c76c880a8#file-allow-url-patterns-intercept-protocol-diff-L186
Sorry for confusing anyone with the previously posted code excerpt (deleted) for a single page / single file app. There was more going on the code so it just appeared as if it worked, but manual interception of the first request was actually done, and a page reload had to be done twice for the app to actually load.
I'm now using the code below, which intercepts the following (first) request and delivers the app code, whenever the page is loaded (or reloaded).
let internal_url = 'https://my-internal-domain/webcontent.html';
win.webContents.on('did-start-loading', function(e) {
protocol.interceptBufferProtocol('https', function(request, respond) {
protocol.uninterceptProtocol('https');
if (request.url !== internal_url) {
console.warn('something went wrong');
} else {
let content = fs.readFileSync(app_folder + '/webcontent.html');
respond(content);
}
});
});
win.loadURL(internal_url);
Sorry for confusing anyone with the previously posted code excerpt (deleted) for a single page / single file app. There was more going on the code so it just appeared as if it worked, but manual interception of the first request was actually done, and a page reload had to be done twice for the app to actually load.
I'm now using the code below, which intercepts the following (first) request and delivers the app code, whenever the page is loaded (or reloaded).
let internal_url = 'https://my-internal-domain/webcontent.html'; win.webContents.on('did-start-loading', function(e) { protocol.interceptBufferProtocol('https', function(request, respond) { protocol.uninterceptProtocol('https'); if (request.url !== internal_url) { console.warn('something went wrong'); } else { let content = fs.readFileSync(app_folder + '/webcontent.html'); respond(content); } }); }); win.loadURL(internal_url);
thanks,@neuralisator . I also add a flag , orelse it will go to the 'something went wrong' when I send other XHR request after the index page loaded.
let isEverReg = false
win.webContents.on('did-start-loading', function () {
if (isEverReg === true) {
return
}
isEverReg = true
protocol.interceptBufferProtocol('http', function (request, respond) {
protocol.uninterceptProtocol('http')
if (request.url !== URL) {
mainLogger.info('something went wrong:' + request.url)
} else {
const filePath = `${join(__dirname, '../../dist/renderer/index.html')}`
const fileContent = readFileSync(filePath)
mainLogger.info('Index page read successfully.')
respond({
statusCode: 200,
data: fileContent
})
}
})
})
any news
We are helpless
hello?
any update ?
Updaaaaaaaaate pls :pleading_face:
any updates?
any updates or plan?
@zcbenz Hi! I have searched for a while to resolve my problem: I need to intercept http protocol ONLY for specific urls. I think suggestion posted in this issue is one acceptable resolution.
Maybe we should try patch in this comment? I fully understand that for the electron team, this feature may not be the highest priority, but it may be important for the developers in this issue. If possible, I would like to receive an official response: will the patch in this thread be considered? If so, I can help push for this change.
I have not compiled chromium or electron myself before, only v8. I know that compiling chromium-based applications is a long process. But to solve this problem, I will pull the source code soon and set up the necessary tools such as gclient/gn/ninja, and then try some modifications. If the solution is feasible, I hope to receive official feedback and assistance at that time.
any news ? In new electron version, cookie samesite=none
must be used with https
while our server is still http
. Our project use local html files and request the http server, so the set-cookie
header is useless.
It seems v25 to fix the issue.
https://github.com/electron/electron/blob/main/docs/breaking-changes.md
Deprecated: protocol.{register,intercept}{Buffer,String,Stream,File,Http}Protocol The protocol.registerProtocol and protocol.interceptProtocol methods have been replaced with protocol.handle.
The new method can either register a new protocol or intercept an existing protocol, and responses can be of any type.
request headers are also important, and existing apis don't get them right
Hello, Any news on this ? Thanks
Is your feature request related to a problem? Please describe. It's possible to intercept schemes (including built-ins like
http:
,https:
, andfile:
), but doing so requires you to handle all requests for that scheme, there's no way to fall-through to the original handler as far as I can tell. Neglecting to callcallback(...)
simply makes the request hang.Using
protocol.interceptHttpProtocol('http', ...)
will lead to an infinite loop if you usecallback(request)
. This prevents using the intercepts to do handy things like set a header on all HTTP requests to a certain domain, or blackholing another (useful for preventing tracking, ads, etc):Being able to selectively handle requests for an intercepted protocol would be very useful. It would provide the ability to use
protocol.interceptFileProtocol('http', ...)
and only intercept certain requests, such as those with the originhttp://localhost/
. This would allow you to simulate local files as being served over HTTP, getting around several of the limitations of thefile://
protocol. Currently there's no easy way to do this as you'll intercept all HTTP requests and lose the ability to talk to the network (at least over HTTP). Even if your handler could retrieve the content, it would have to give it a file path so that the callback can return the path to the file, or you'd need to use thestring
/buffer
/stream
variants and open any files yourself and provide the content that way. Neither is very clean. You can also bundle a local web server, but this is overkill most of the time.I've found this particularly painful for trying to get WebAuthn working without a server in the loop, as Chromium only allows the API for
https
domains, orhttp://localhost
, notfile://
(or any other protocol). An intercept seems like a perfect fit for this, except you can't selectively handle that small case.Selective handling also opens the ability to make protocol handlers in the future act more like middleware which is composable and reusable. If interceptors could be applied like a stack and pass to the next interceptor, you could have libraries which handle things like setting certain headers.
Describe the solution you'd like I think this can be solved with a somewhat minor change to the API. There may be dragons in the implementation, I've glanced at the code which implements the
protocol
module, but I'm not too familiar with it.My suggested solution would be to add a third argument to the handler function for the
protocol.intercept{Any}Protocol
functions callednext
, and rename thecallback
argument todone
.done
would have the same behavior as the currentcallback
but the name change makes it more explicit that it will end processing of the request. The new argument,next
, would fall through to the original handler, the one which would be restored byprotocol.uninterceptProtocol
.next
would optionally take a request object, allowing you to modify it before passing it along, such as setting a header, or changing the URL allowing redirecting between files.So, the intercept earlier which currently causes an infinite loop could be written as:
You could also write a handler which pretended to be
http://localhost
by reading files from disk:Or make
file://
check cloud storage if the file isn't found locally:Combined with intercepting a custom protocol: