我的Vue.js应用程序中有一个组件,使用Axios将表单中的电子邮件提交给Mailchimp。
我已经读过要在Mailchimp的帖子网址中浏览CORS,我需要使用post-json
版本并在网址末尾添加&c=?
。我还将我的请求方法从POST
更新为GET
并序列化了表单输入。
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>
使用上面的代码,我仍然会收到以下错误:
无法加载https://example.us15.list-manage.com/subscribe/post-json?u=xxx&id=xxx&c=?:No&#39; Access-Control-Allow-Origin&#39;标头出现在请求的资源上。起源&#39; http://localhost:8080&#39;因此不允许访问。
我是否缺少一步?
答案 0 :(得分:2)
您的服务器(后端)必须使用完全相同的标头进行响应。
即:https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
例如Axios获取/发布(没关系):
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);
});
例如服务器端。我喜欢Symfony4并使用NelmioCorsBundle,请查看allow_origin: ['*']
。如果你使用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\.']
如果您不是直接使用服务器,请与供应商核实此细微差别。
此标头也可以通过Nginx传输,这不是最好的主意。
例如,请查看:
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;
}
如果没有数据传递则删除Content-Type值得注意。必须始终传输数据或null
。这很奇怪,这是误导。