我使用SLIM Micro-Framework构建了一个API。我设置了一些使用以下代码添加CORS头的中间件。
class Cors{
public function __invoke(Request $request, Response $response, $next){
$response = $next($request, $response);
return $response
->withHeader('Access-Control-Allow-Origin', 'http://mysite')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
}
}
对于我的前端,我使用了VueJS。我设置了VueResource并使用以下代码创建了一个函数。
register (context, email, password) {
Vue.http({
url: 'api/auth/register',
method: 'POST',
data: {
email: email,
password: password
}
}).then(response => {
context.success = true
}, response => {
context.response = response.data
context.error = true
})
}
在chrome中,控制台会记录以下错误。
XMLHttpRequest cannot load http://mysite:9800/api/auth/register. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mysite' is therefore not allowed access.
奇怪的是,GET请求完美无缺。
答案 0 :(得分:2)
实际上CORS是在浏览器级别实现的。甚至用
return $response
->withHeader('Access-Control-Allow-Origin', 'http://mysite')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
chrome和Mozilla不会设置标题以允许交叉来源。所以,你需要强制禁用..
阅读有关禁用CORS的更多信息
答案 1 :(得分:2)
你在这里解决方案的一半。
您缺少的是OPTIONS路线,其中还需要添加这些标题。
$app->options('/{routes:.+}', function ($request, $response, $args) {
return $response
->withHeader('Access-Control-Allow-Origin', 'http://mysite')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
});
答案 2 :(得分:1)
这是因为预检请求属于OPTIONS类型。您需要在请求上创建一个事件侦听器,它会检查类型并发送带有所需标头的响应。
不幸的是我不知道Slim框架,但这是Symfony中的工作示例。
首先要返回的标题示例:
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="10dip"
android:paddingBottom="10dip"
在请求侦听器中,有一个onKernelRequest方法可以监视所有正在进入的请求:
// Headers allowed to be returned.
const ALLOWED_HEADERS = ['Authorization', 'Origin', 'Content-Type', 'Content-Length', 'Accept'];
这里我只是重现了Origin(允许所有域请求资源,您应该将其更改为您的域)。 希望它会给一些胶水。
答案 3 :(得分:1)
CORS可能很难配置。关键是您需要在服务器和客户端设置特殊标头,并且我没有看到任何Vue标头设置,除此之外我知道http
不是一个功能。但是这里有一些邮政请求的设置。
const data = {
email: email,
password: password
}
const options = {
headers: {
'Access-Control-Expose-Headers': // all of your headers,
'Access-Control-Allow-Origin': '*'
}
}
Vue.http.post('api/auth/register', JSON.stringify(data), options).then(response => {
// success
}, response => {
// error
})
请注意,您需要对数据进行字符串化,并且需要公开标头,通常包括Access-Control-Allow-Origin
标头。
我在自己的一个应用程序中做的是定义拦截器,所以我不担心为每个请求设置标头。
Vue.http.headers.common['Access-Control-Expose-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, x-session-token, timeout, Content-Length, location, *'
Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'