sapper icon indicating copy to clipboard operation
sapper copied to clipboard

Base url for server fetch requests

Open imbolc opened this issue 7 years ago • 4 comments

Now fetch used with an relative path requests different urls from browser and server. Eg if we're on page foo.com and requesting /api/bar.json, browser would request foo.com/api/bar.json, but server 127.0.0.1:PORT/api/bar.json.

In my case (and I think it's a pretty common one) we already have api written on different language, so I'm using nginx to join it with sapper under the same domain name. But as api actually serves on a different port than sapper does, fetch from server side doesn't work. It requests 127.0.0.1:SAPPER_PORT while api is on 127.0.0.1:API_PORT.

I have proxy_set_header Host $host; in my nginx config and Express parses it into req.hostname. But as @mrkishi suggested we probably can't use it in fetch by default as anyone can forge this header and trigger server requests to any domains.

So it may be a setting to enable parsing of the header or just an FETCH_ORIGIN=https://foo.com environment variable. I'd vote for the second option as it doesn't rely on proper proxy server configuration.

imbolc avatar Oct 23 '18 04:10 imbolc

I have a similar problem. If you worry about security you can provide the same option as exist in express:

app.set('trust proxy', 'loopback')

stalkerg avatar Aug 12 '19 10:08 stalkerg

I'd like this as well. I've written a backend in Java and would like to send my fetch calls for JSON data to that server (e.g. api.mydomain.com or mydomain.com/api)

benmccann avatar May 11 '20 21:05 benmccann

I get around this in userspace, with an extremely light wrapper around fetch - https://github.com/beyonk-adventures/sapper-httpclient

antony avatar May 12 '20 07:05 antony

I've been thinking more about how to best do this. The preferred way might be to use the same domain and have an application load balancer like nginx split traffic on the URL path (e.g. /api). This is for two reasons. Firstly, you might not necessarily want to cookie the primary/apex domain and have the cookie shared across all subdomains. You also might not want to do CORS because preflight requests add latency and CORS adds complication. You might want to setup a proxy in Express for dev mode to avoid having to setup nginx locally for development

You can either check user authentication in Node or in the API server. It's probably easier to do it in the API server so that sapper can be dumber and doesn't need a connection to the DB. In either case, you want the sapper express server to do two things:

  1. pass along the cookies and any authentication information
  2. contact the API layer using internal DNS hostname of the API service for better latency. It can go straight to the application load balancer instead of passing through the external load balancer first

The first one doesn't work particularly well today (https://github.com/sveltejs/sapper/issues/881). The combination of the two definitely won't work because the server checks that the hostnames match, which they wouldn't if you're using an internal hostname. I opened a PR (https://github.com/sveltejs/sapper/pull/1188) that would allow setting a different hostname, but doesn't really help with the auth problem. It might be a good reference for how to change the host on the server, but I'm going to close it for now in favor of a more holistic solution that handles changing the host and handling auth together

benmccann avatar May 14 '20 03:05 benmccann