Open kyllerss opened 1 year ago
@kyllerss setting the hostname to get around CORS seems like a magic bullet, but I don't believe it's meant to be used this way. That's why Capacitor is including a patched fetch
that ignores CORS / cross origin cookie issues. It's currently buggy though (#6177) so a lot of people use this plugin: https://github.com/silkimen/cordova-plugin-advanced-http . If using the latter, watch out for: https://github.com/silkimen/cordova-plugin-advanced-http/issues/492
You can sort of see the documentation here: https://capacitorjs.com/docs/config
Under server.iosScheme
it clarifies that Can't be set to schemes that the WKWebView already handles, such as http or https so that means that, at least on iOS, you'd be unable to share cookies because the schemes wouldn't match. That is, your faked server origin would be something like capacitor://www.my-domain.com/
hitting something like https://www.my-domain.com/
and those are not the same origin.
That's my understanding, but it could be wrong. If just "faking" the hostname is all it takes to bypass all CORS/cookie/fetch issues that'd be amazing.
Thanks for the answer @silviogutierrez . It's disappointing that there isn't a simple solution to this issue. I suppose my confusion comes from using SvelteKit, which handles much of the communication between client and servers implicitly (SvelteKit handles a page's SPA lifecycle by orchestrating server fetches and managing state behind the scenes). Unless someone explicitly fetches state from a given server endpoint, they will be relying on SvelteKit's internals to send server requests which will end up going to the localhost
instance in the packaged binary (someone please correct me if SvelteKit has some way of addressing this). This nuance regarding what the WebView considers the host context will cause people some confusion and frustration.
For the sake of others out there, I think it would be a good idea to add a note to the documentation that points out the issues that people will run into with SvelteKit-style frameworks (ie. frameworks that glue together back-end code and front-end code seemlessly). Perhaps it is not an emergency now, but I can imagine this will continue to come up as these frameworks gain more adoption.
I was caught in this trap when trying to call my API which was on example.com/api and my hostname was set to example.com. It was routing all API requests to itself. Needed to move the API to a subdomain, will likely have to do that for all assets too. Combine that with plugins/features failing due to having an insecure host on iOS if you do change it, I might have to stick with localhost. Shame I won't be able to use autofill/password manager integration as a result however
This is also the recommended setup to support password autofilling, ref. https://capacitorjs.com/docs/guides/autofill-credentials. This makes it very hard to achieve both password autofill & e.g. serving images or perform API calls to & from the same domain in the same app.
I had the exact same issue like @alexcroox @emmernme. I set up password autofilling by following the docs and it wasn't working properly on Android. I ended moving my API from domain.com/api/ to api.domain.com/api/. I also had to start serving some of my assets through api.domain.com. So it's possible to make it work but it's not really straightforward. It would at least help if there was a mention in the official docs. There's even a pull request in the docs repo but it's been waiting for a review for half a year.
A fix might be to allow a URL path to be ignored from the internal routing. Eg /api/*
My backend automatically redirects https://host.com to https://www.host.com. I was able to use https://www.host.com for the autofill-credentials and https://host.com for the backend API. Not a great workaround, but it works. It would be great if we had a correct solution for this.
are there any plans to resolve this issue? for example, to enable configuring URL path to be ignored from the internal routing, as @alexcroox suggested.
I was facing exact problem a minute ago. I realized that we don't need hostname to solve cors for calling apis from different server. I updated it like this:
"server": {
"androidScheme": "https",
"allowNavigation": [
"domain.com",
"*.domain.com"
]
}
My api is running at domain.com/api. After updating like this it worked for me.
Bug Report
After reading the documentation as to how Capacitor works behind the scenes, it is unclear as to what the expected behavior should be when invoking APIs. Here is my understanding vs what I am seeing on my end:
localhost
server.localhost
vs API endpoint domain), one can set theserver.hostname
property incapacitor.config.json
to match the endpoint domain.Something that I am finding confusing which requires clarification in the documentation is how the capacitor router works when it is trying to distinguish requests intended for a remote server endpoint versus the static-asset-serving instance within Capacitor. Often static assets are hosted in the same domain as the API endpoints.
I assume that all requests go through the Capacitor router (static and API endpoints) and that it would determine if the requested endpoint matched an existing static asset and forward the request off to the matching server endpoint if it didn't find a matching static asset. Either this is a misunderstanding on my behalf on how the internal
localhost
instance works and could use some clarification in the documentation, or my assumption is correct and I have some misconfiguration on my end that needs fixing.This is what I am seeing when setting the
hostname
parameter to match my single domain:Based on the above error (
Unable to open asset URL: <api endpoint>
), it seems as if Capacitor is treating all URLs as static assets. If that is the case, then what is the expected best practice for thehostname
setting? How can someone make API endpoint calls when thehostname
setting is set?Would be helpful if some best practices were documented on how to handle cookies, remote endpoints, and static assets that would clarify similar misunderstandings.
Capacitor Version
Platform(s)
Android
Current Behavior
Non-static assets requests are rejected.
Expected Behavior
Unclear expectations when setting
hostname
server property.Code Reproduction
Other Technical Details
npm --version
output: 8.19.2node --version
output: v16.18.0Additional Context
Ideally, Capacitor would serve static assets when present, and proxy request to endpoint when missing (as would be the case with dynamic URLs, or API endpoints).
I have a locally-running webserver that is serving the endpoints over HTTPS. My
capacitor.config.json
is as follows (obfuscated):I am using SvelteKit with a custom script that handles the build process. I also have an entry in my /etc/hosts file for www.my-domain.com along with a self-signed cert I have installed system-wide.