One workaround I've used in the past, when I've been unable to update the backend/server is to proxy the request through a "repeater" using an AWS API Gateway and a small Lambda function. It's not ideal, but in some cases, like when the API is not yours, or you cannot touch the code, it is necessary.
Obviously, it adds a little overhead/latency and I wouldn't recommend if you can update your service. And it doesn't really work in dev, if you're changing the response... However...
My Lambda function looks like this:
const https = require('https');
const { URL } = require('url');
exports.handler = async (event) => {
return makeRequest(event).then(body => {
return JSON.parse(body);
}, (error) => {
return { message: error.message, event };
});
};
function makeRequest(event) {
return new Promise((resolve, reject) => {
let responseBody = '';
const url = new URL(event.url);
const options = {
host: url.hostname,
path: url.pathname,
port: url.protocol === 'https:' ? 443 : 80,
protocol: url.protocol,
method: event.method,
headers: {
'Content-Type': 'application/json'
}
};
const req = https.request(options, (res) => {
res.on('data', (d) => {
responseBody+=d;
});
res.on('end',function(){
resolve(responseBody);
});
});
req.on('error', (e) => {
reject(Error(e.message));
});
req.write(JSON.stringify(event.data));
req.end();
});
}
I don't have any sort of CLI instructions, so here's a run down of the config in AWS web interface. You can configure security in many ways if needed including an API key:
- Create a new Lambda function with the name of your choice using Node.js 8 and a new or existing role and entert he above script into the Function Code input area.
- Go to the Amazon API Gateway section of the AWS Console and create a New API with the name of your choice.
- From the Actions dropdown, select 'Create Method', choose 'POST' and save.
- In the resulting endpoint config page, choose 'Lambda Function' as the integration type, leave 'Use Lambda Proxy integration' unchecked, select your Lambda function and save.
- From the Actions dropdown, select 'Enable CORS' and then click the button to confirm
- Unfortunately, this doesn't add all the CORS headers to the POST endpoint so from the menu on the left, click POST and then click the 'Method Response' box.
- Click the toggle on the 200 response and add two more headers: Access-Control-Allow-Headers and Access-Control-Allow-Methods
Go back to the Method Execution/POST screen and click the 'Integration Response' box.
- Toggle the 200 response and then the Header Mappings and add 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token' to the Access-Control-Allow-Headers header and 'POST,OPTIONS' to the Access-Control-Allow-Methods header.
- From the Actions dropdown, select 'Deploy API', select 'New Stage' and give it a name (e.g. 'production' or 'beta').
This will give you an endpoint. Make a POST request to it with the following JSON body and you're done.
{
"url": "https://some-non-cors-enabled-api.com/",
"method": "POST",
"data": {}
}
GitHub