Help

Trigger webhook from HTML form submission — CORS error

Topic Labels: Automations
Solved
Jump to Solution
2721 4
cancel
Showing results for 
Search instead for 
Did you mean: 
jamesvclements
6 - Interface Innovator
6 - Interface Innovator

Fetch request is built like this, including these headers:
CleanShot 2021-10-14 at 19.52.10

But it returns a CORS error — the webhook isn’t returning Access Control Allow Headers…

CleanShot 2021-10-14 at 19.47.03

Oddly enough I can get it to work from Postman:
CleanShot 2021-10-14 at 19.53.56

And if I follow the proxy outlined here it works as well.

Is there a way to make the webhook return that header? Or another solution? Thanks!

1 Solution

Accepted Solutions

Thanks for the details.

Erin from the community team reached out to confirm that the incoming webhook trigger doesn’t currently support CORS. The reason it works on Zapier / Postman is because they execute the requests from their servers, rather than the browser.

For now I’m just going to keep it simple and use Zapier rather than abandoning CORS, and hope Airtable Webhooks support CORS at some point in the near future.

See Solution in Thread

4 Replies 4
jamesvclements
6 - Interface Innovator
6 - Interface Innovator

For more context, I tested it out with Zapier Webhook and it passed when I removed all the headers from the fetch options:

const fetchOptions = {
    method: 'POST',
    body: formDataJsonString,
};

but this same header-less payload still returns a CORS error with Airtable’s Webhook.

Users don’t currently have any control over how Airtable’s webhook automation trigger responds to requests (and I doubt that we ever will). I recommend reaching out to Airtable support directly (in the app: Help → Contact support). While Airtable staffers do frequent the forum, they prefer to be approached directly with support requests, and this leans pretty heavily in that direction IMO.

That aside, have you tried the “no-cors” mode that was recommended in the error message you received (seen in your screenshot)? I’ve only called Airtable webhooks from within other Airtable scripts, so I haven’t needed to test this workaround and therefore don’t know how exactly it should be applied, but it’s probably worth investigating.

Thanks for the details.

Erin from the community team reached out to confirm that the incoming webhook trigger doesn’t currently support CORS. The reason it works on Zapier / Postman is because they execute the requests from their servers, rather than the browser.

For now I’m just going to keep it simple and use Zapier rather than abandoning CORS, and hope Airtable Webhooks support CORS at some point in the near future.

Adding to @jamesvclements response for anyone who lands here in the future:

"What" In plain english:
- AirTable Webhooks DO NOT accept requests coming from Browsers (your website, google tag manager, javascript on your website).
- Zapier Webhooks DO accept requests coming from Browsers.
- Google Cloud Functions DO accept requests coming from Browsers

"WHY" in plain english:
- AirTable Webhooks are/were made for "server to server" interactions: Zapier, Slack, Todoist, ActiveCampaign, etc all these SAAS Tools (including your own) CAN hit an AirTable Webhook because the SAAS Tool's SERVER and not the browser will be making the request
- Zapier Webhooks allow both because when they were designed, the Zapier team decided they would indeed entertain use-cases such as Google Tag Manager or JavaScript on your Website to send data to Zapier to trigger some automation. For example, if you've gone bonkers and want a slack notification everytime someone visits your website, you can totally use Zapier for that. Google Tag Manager or JavaScript on your Website --> Zapier Webhook --> Slack Notification
- Google Cloud Functions: they are designed to be more special. You can set a "policy" in your Google Cloud Function to accept or reject requests coming from specific domains. Neither Zapier or AirTable allow you to set such a policy. 

What is CORS? It's a fancy word for Policy.
AirTable Policy --> AirTable CORS Policy = no requests from browsers allowed, requests from servers allowed
Zapier Policy --> Zapier CORS Policy = requests from browsers and servers allowed
Google Cloud Function Policy --> Google Cloud Function CORS Policy = you can decide who is and who isn't allowed to make a request regardless of whether the request is coming from a browser or server

Now that you have context, let me define CORS: Cross Origin Resource Sharing is a set of rules that define how a request to an "origin" (domain) other than yours (i.e your domain) can make a request. If your website is "joanna.com", CORS will first ask "yourfriend.com" whether they allow requests from "joanna.com".
- If "yourfriend.com" says NO, then CORS blocks the request.
- If "yourfriend.com" says YES, then CORS allows the request. 

  • Communicating Policies via Headers: When a web page makes a cross-origin request, the server (yourfriend.com) can include specific CORS (policy) headers in its response. Naturally, this comes from the CORS Policy set at the Server (yourfriend.com). For example, if you are making a call to a Google Cloud Function (yourfriend.com), you would set the CORS policy in the Google Cloud Function ((yourfriend.com)

  • The headers from the CORS Policy, returned by the server (e.g Google Cloud Function) tell the browser whether the request is permitted or rejected.

  • Server's Control: The server ((yourfriend.com) specifies which origins are allowed, which HTTP methods are acceptable, and what headers can be included in requests. This is the server's CORS policy. Key headers in a CORS Policy include Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers.

  • Browser Enforcement: Browsers have a default security policy, known as the same-origin policy, which restricts web pages from making requests to a different domain (e.g yourfriend.com) than the one that served the web page (joanna.com) . This is a fundamental security measure to prevent potentially malicious scripts on one page from interacting with sensitive content on another.

  • CORS as an Extension: CORS (Cross-Origin Resource Sharing) is a set of rules and headers that define how browsers and servers can interact for cross-origin requests. CORS provides a way for servers to tell browsers that it's safe to allow requests from certain origins.