I have several netlify functions configured. One of them, just one of them, is giving me the dreaded HTTP 302 response CORS error when consumed from a browser on another domain.
All my netlify function endpoints are configured in the netlify.toml file and all follow the following format:
[[redirects]]
from = "/api/gift/:txHash"
to = "/api/_gift?txHash=:txHash"
status = 301
[[redirects]]
from = "/api/_gift"
to = "/.netlify/functions/gift"
force = true
status = 200
All of them work correctly when consumed from a browser on a different domain except for one.
The one that does not work can be fetched from Postman just fine (HTTP 200 response). When I do so I can clearly see the response headers correctly being sent.
And yet one of them, just one, returns the HTTP 302 CORS error when invoked from a browser from a different domain. Why? How can this be resolved?
The issue can be seen clearly here. Invoking https://cryptomint.one/api/gift/some-test-tx-hash from Postman returns a valid JSON HTTP 200 response and valid access-control headers. Invoked from a browser (in this case from localhost) and this is observed.
If I hit https://cryptomint.one/.netlify/functions/gift?txHash=some-test-tx-hash directly from the browser it works with an HTTP 200 response. So something to do here with the redirects configuration not playing nicely for some reason. Note that hitting netlify/functions directly is not a solution.
Not so. The Access-Control-Allow-Origin = "*" response header is there to allow access from anywhere.
So my issue is this. /api/gift/:txHash fails with a CORS error HOWEVER if I hit /.netlify/functions/gift?txHash=:txHash directly it works perfectly.
This fact means there MUST then be something wrong with my redirect configuration in the toml file (see above) OR alternatively some other issue going on.
That’s what I want to resolve but I have been unable to despite many many hours of effort.
[[redirects]]
from = "/api/gift/:txHash"
to = "/api/_gift?txHash=:txHash"
status = 200
[[redirects]]
from = "/api/_gift"
to = "/.netlify/functions/gift"
force = true
status = 200
You’re using double proxy, that is /api/gift/ to /api/_gift and then /api/_gift to /.netlify/functions/gift. This won’t work. We only allow a single proxy on a request. Otherwise it results in a 404.
Also, you’ve this:
[[headers]]
for = "/.netlify/functions/*"
[headers.values]
Access-Control-Allow-Origin = "*"
Access-Control-Allow-Headers = "Content-Type"
Access-Control-Allow-Methods = "GET, HEAD, PUT, POST, OPTION"
This has no effect and is redundant as Functions are unaffected by these headers.
I think you can simplify the rewrite by:
[[redirects]]
from = "/api/gift"
to = "/.netlify/functions/gift"
force = true
status = 200
200 rewrites preserve query string parameters so you could make a request like: /api/gift?txHash=some-test-tx-hash and it would redirect fine.
This is precisely how I originally configured my endpoints. Alas it did not work. Hence the move to more convoluted approaches. After a bit of testing I can see
Query String Parameters that already exist in a URL will be passed on as is. Even if you need to access the path inside your functions, you can make it like event.path + '/' + event.queryStringParameters.txHash.
I agree with @eddyoc that the current inability to alias placeholder values in as query string parameters isn’t ideal, especially if it behaves in an undocumented inconsistent fashion by working with 302/301 but not 200.
I was going to lodge an issue against this repository:
But a quick check makes me believe the issue isn’t the parsing, since this:
Which looks correct to me, at least compared to the results of the other unit tests.
In particular it isn’t inadvertently stripping the query string parameters which I’d though may have been the case.
So the limitation/issue could be occuring after the parsing at the implementation level.
Is there a better spot that I can lodge a ticket so it doesn’t get forgotten?
So in the end I simply ran with the simple configuration
[[redirects]]
from = "/api/gift/:txHash"
to = "/.netlify/functions/gift/:txHash"
status = 200
The parameters are not exposed from event.pathParameters in the handler unfortunately but wrote my own url parser to extract them from the rawUrl. Suboptimal but unblocks us until a more robust solution comes along.
Yeah, that’s what the team said to the question I asked them before my weekend. Functions will only see the original URL where the request was made, and not see the resolved URL, thus the problem.
@nathanmartin have you filed the issue somewhere? If not, I’ll be filing one for the team to work on and would like to avoid duplicating it.
I haven’t had the chance to lodge an issue anywhere as I’ve been handling unrelated client work, it’d be great it you could file it in the appropriate spot for the team to look at.
I’d completely understand if it can’t be solved easily too, in which case it might just be worth mentioning the limitation in the docs.