Vue.js HTTP request to webhook endpoint fails with cross-origin error

I’m having trouble sending form data to a webhook URL from my Vue application. Every time I try to submit the form, I get cross-origin policy errors.

Here’s my contact form setup:

<form @submit.prevent="handleSubmit()" class="form-container">
    <input class="input-field" type="text" name="fullName" id="fullName" v-model="fullName" placeholder="Full Name" required>
    <input class="input-field" type="email" name="userEmail" id="userEmail" v-model="userEmail" placeholder="[email protected]" required>
    <input class="input-field" type="text" name="projectTitle" id="projectTitle" v-model="projectTitle" placeholder="Project Title" required>
    <input class="input-field" type="url" name="projectUrl" id="projectUrl" v-model="projectUrl" placeholder="Project URL" required>
    <textarea class="input-field" name="description" id="description" v-model="description" rows="4" placeholder="Tell us about your project..."></textarea>
    <input class="input-field" type="text" name="linkedinHandle" id="linkedinHandle" v-model="linkedinHandle" placeholder="LinkedIn">
    <input class="input-field" type="text" name="githubHandle" id="githubHandle" v-model="githubHandle" placeholder="GitHub">
    <button class="submit-btn" type="submit">Send Application</button>
</form>

And here’s the Vue component handling the submission:

<script>
import axios from 'axios';

export default {
    name: 'ApplicationForm',
    data() {
        return {
            fullName: '',
            userEmail: '',
            projectTitle: '',
            projectUrl: '',
            description: '',
            linkedinHandle: '',
            githubHandle: ''
        }
    },
    methods: {
        handleSubmit() {
            axios.post('hooks.zapier.com/hooks/catch/WEBHOOK_ID', {
                fullName: this.fullName,
                userEmail: this.userEmail,
                projectTitle: this.projectTitle,
                projectUrl: this.projectUrl,
                description: this.description,
                linkedinHandle: this.linkedinHandle,
                githubHandle: this.githubHandle
            })
            .then((result) => {
                console.log('Success:', result);
            })
            .catch((err) => {
                console.log('Error:', err);
            });
            
            alert('Application submitted successfully!');
        }
    }
}
</script>

The browser console shows these errors:

Access to XMLHttpRequest blocked by CORS policy: Request header 'content-type' is not allowed by Access-Control-Allow-Headers in preflight response.

Access to XMLHttpRequest blocked by CORS policy: The request client is not a secure context.

How can I fix this cross-origin issue when sending data to the webhook endpoint?

Yeah, that CORS error is super common with webhook endpoints from browsers. Zapier and similar services don’t set up their endpoints for direct browser requests - they expect server-to-server communication. I spotted something in your code though. You’re missing the protocol in your axios URL. Should be https://hooks.zapier.com/hooks/catch/WEBHOOK_ID instead of just the domain. Won’t fix your CORS problem, but still needs the https. Here’s what actually worked for me: ditch axios and use a hidden form instead. Create it programmatically and submit it - this sidesteps CORS entirely since browsers treat form submissions differently than AJAX requests. Just heads up that you won’t have the same response control you get with axios, so plan for handling redirects differently.

I’ve encountered the same CORS problem with webhooks before. Services like Zapier often don’t set CORS headers properly, resulting in browsers blocking direct requests from your Vue application due to cross-origin security policies.

To resolve this issue, consider creating a proxy endpoint on your own server. This way, instead of posting directly to the webhook from Vue, you send your form data to your server first, which then forwards it to the webhook, effectively bypassing CORS issues since communication is server-to-server.

If you prefer not to set up a backend, you can utilize Netlify Functions or Vercel Functions to implement a simple proxy. Just ensure you configure the appropriate CORS headers on your proxy to allow requests from your domain.

CORS is a nightmare with webhooks, but here’s another fix - use JSONP or switch to a form element with method=‘post’ and target=‘_blank’. Browsers don’t block regular form submissions like they do XHR requests. Just ditch the @submit.prevent and let the form submit naturally. You’ll lose the promise handling, but it actually works.