Closed birjj closed 2 years ago
Just double checked how I'm passing the origin to Apollo server and it seems to be the correct way.
type StaticOrigin = boolean | string | RegExp | (boolean | string | RegExp)[];
type CustomOrigin = (requestOrigin: string | undefined, callback: (err: Error | null, origin?: StaticOrigin) => void) => void;
That's basically what I'm doing: https://github.com/electerious/Ackee/blob/ba976a89dcde893371b881d5fc4496cfb1c2625c/src/serverless.js#L51
I'm not sure what's happening with the headers.
Yes, as far as I can see you're passing it correctly. I've been debugging this for a few hours with various logs and workaround attempts, but so far it seems like Vercel might not be passing the headers, or something else is happening between the Apollo server and the client. I'll report back if I figure out what's going wrong.
Thanks for the help!
That's how the response of the handler looks when I log it. There is a access-control-allow-origin
and a access-control-allow-credentials
, but I'm not sure what happens to the allowedHeaders
.
{
statusCode: 200,
body: '[{"data":{"facts":{"id":"e875350a-09ae-59bf-ae72-2ae687ba00db","activeVisitors":0,"__typename":"Facts"}}}]\n',
multiValueHeaders: {
'x-powered-by': [ 'Express' ],
'access-control-allow-origin': [ 'https://example.com' ],
vary: [ 'Origin' ],
'access-control-allow-credentials': [ 'true' ],
'content-type': [ 'application/json; charset=utf-8' ],
'content-length': [ '107' ],
etag: [ 'W/"6b-LOgac06NQapfhEsmrItvJVDfH1c"' ]
},
isBase64Encoded: false
}
Thanks, that's great for debugging. I think that might've helped me uncover a related bug:
ACKEE_AUTO_ORIGIN=true
)Regardless, the headers still aren't being returned to the browser for some reason. It looks like multiValueHeaders
is just AWS specific syntax for setting headers, so it should work - I'll keep digging to see if I can force it to work.
*
Finally! I think I've finally found the issue, thanks to your log @electerious: the AWS Lambda API is poorly documented, but seems to use both .headers
and .multiValueHeaders
to define headers. The Vercel shim that lets us run the serverless function without coding it specifically for Vercel seems to lack support for .multiValueHeaders
.
The issue is fixed if we convert .multiValueHeaders
to .headers
:
// api/index.js
'use strict'
/**
* A serverless function handler for the '/api' route, for use with Vercel.
* This handler follows the AWS Lambda API; Vercel deployments are opted-in
* using the "NODEJS_AWS_HANDLER_NAME" environment variable defined in vercel.json.
*
* See:
* - https://vercel.com/docs/serverless-functions/supported-languages#node.js
* - https://vercel.com/docs/runtimes#advanced-usage/advanced-node-js-usage/aws-lambda-api
*/
const handler = require('../src/serverless').handler
const convertMultiValueHeaders = (response) => {
if (!(response instanceof Object) || !('multiValueHeaders' in response)) {
console.log('No multiValueHeaders, not converting')
return response
}
response.headers = response.headers || {}
for (const [ key, value ] of Object.entries(response.multiValueHeaders)) {
if (value.length === 1) {
response.headers[key] = value[0]
}
}
return response
}
exports.handler = async (...args) => {
const response = await handler(...args)
console.log('Response before conversion:', response)
const converted = convertMultiValueHeaders(response)
console.log('Response after conversion:', response)
return converted
}
I'll create a PR shortly
I've opened a support case with Vercel, which they say they'll try to respond to within 3-5 business days.
Would you like me to create a PR to fix this in Ackee @electerious, or should we wait for Vercel to respond and (possibly) update their AWS Lambda API shim?
Thanks a lot for your work! This would have taken me forever to figure out. A PR is welcome :)
Pushed a new version of Ackee. Please let me know if everything works now! :)
新版本还是Unexpected token A in JSON at position 0
Looks like it works! Thanks for the merge @electerious
For reference I've opened a public issue on Vercel's side (vercel/vercel#7820), which anyone interested can track for when this gets fixed on Vercel's end.
🐞 Describe the bug
After deploying Ackee to Vercel and setting
ACKEE_AUTO_ORIGIN=true
, I am not seeing any CORS headers in response to theOPTIONS ackee.example.com/api
request (whereexample.com
is replaced with my domain). I have also tested withACKEE_ALLOW_ORIGIN=site.example.com
, with the same result. In both cases I'm seeing:📚 To Reproduce
ACKEE_AUTO_ORIGIN=true
💡 Expected behavior
The
OPTIONS /api
response includes CORS headers to allow the tracker script to connect.⚙️ Environment
📋 Additional context
I have validated that the origin handler is called and returns
["site.example.com"]
. It seems that the CORS headers are calculated correctly, but somehow not applied.