Reputation: 584
I have a component in my Vue.js app that submits email from a form to Mailchimp using Axios.
I've read that to get around CORS in Mailchimp's post URL, I need to use the post-json
version and add &c=?
to the end of the URL. I've also updated my request method from POST
to GET
and serialized my form input.
Component.vue
<mailchimp-subscribe action="https://example.us15.list-manage.com/subscribe/
post-json?u=xxx&id=xxx&c=?"></mailchimp-subscribe>
MailchimpSubscribe.vue
<template>
<form @submit.prevent="subscribe">
<input v-model="email" type="email" name="EMAIL" value="" placeholder="Email Address" required>
<input class="button" type="submit" value="Subscribe">
</form>
</template>
<script>
import axios from 'axios'
export default {
name: 'MailchimpSubscribe',
props: {
action: {}
},
data: () => ({
email: '',
response: {}
}),
methods: {
subscribe: function (event) {
axios({
method: 'get',
url: this.action,
data: JSON.stringify(this.email),
cache: false,
dataType: 'json',
contentType: 'application/json; charset=utf-8'
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
}
}
</script>
Using the code above, I still get the following error:
Failed to load https://example.us15.list-manage.com/subscribe/post-json?u=xxx&id=xxx&c=?: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
Is there a step I'm missing?
Upvotes: 1
Views: 7623
Reputation: 4544
Your server (backend) must respond with exactly the same header.
Namely: https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
For example Axios get/post (never mind):
const configAxios = {
headers: {
'Content-Type': 'application/json',
},
};
axios.post('api/categories', configAxios)
.then((res) => {
this.categories = res.data;
console.log(res);
})
.catch((err) => {
console.warn('error during http call', err);
});
For example server-side. I like Symfony4 and it is used NelmioCorsBundle, look at the allow_origin: ['*']
. It's pretty simple, if you use Symfony.
nelmio_cors:
defaults:
allow_credentials: false
allow_origin: ['*']
allow_headers: ['Content-Type']
allow_methods: []
expose_headers: []
max_age: 0
hosts: []
origin_regex: false
forced_allow_origin_value: ~
paths:
'^/api/':
allow_origin: ['*']
allow_headers: ['X-Custom-Auth', 'Content-Type', 'Authorization']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
max_age: 3600
'^/':
origin_regex: true
allow_origin: ['^http://localhost:[0-9]+']
allow_headers: ['X-Custom-Auth', 'Content-Type']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
max_age: 3600
hosts: ['^api\.']
If you are not directly working with the server, then check with your supplier for this nuance.
This header can also be transmitted for example through Nginx, which is not the best idea.
For example, look at the:
add_header Access-Control-Allow-Origin *;
server {
listen 8080;
server_name site.local;
root /var/www/site/public;
location / {
add_header Access-Control-Allow-Origin *;
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/index.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
It is worth paying attention if there is no data passed it removes the Content-Type. The data must always be transmitted or be null
. This is strange and it is misleading.
Upvotes: 2