无法 'GET' CORS 的 mLab 数据 b/c

Cannot 'GET' mLab Data b/c of CORS

我无法使用 getTasks() 函数执行 'GET' 请求。

$(document).ready(function(){
    getTasks();
});

const apiKey = 'xxxxxxx';

function getTasks(){
    $.ajax({
        type: 'GET',
        url: 'https://api.mlab.com/api/1/databases/taskmanager/collections/tasks?apiKey='+apiKey,
        contentType: 'application/json',
        xhrFields: {
            withCredentials: true
        },
        success: function(data){
            console.log(data);
        },
        error: function(){
            console.log('FAIL')
        }
    })
}

我得到的错误是:

api.mlab.com/api/1/databases/taskmanager/collections/tasks?apiKey=xxxxxxx Failed to load resource: the server responded with a status of 400 (Bad Request)​

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 400.

我了解 Windows 上的 Google-Chrome 启用了 CORS,并且(默认情况下)不允许与其他域进行通信。我不确定预检请求是什么。无论如何,我尝试实现我从使用 CORS - HTML5 Rocks​(来自 jQuery 部分的 CORS)中看到的内容,但无济于事。

CORS 可以保护您。如果您想了解更多信息,wikipedia 有一个很好的条目。

这里的问题似乎是您正在尝试直接从您的网络应用程序访问由 mlab 托管的 mongodb。正如您在代码中看到的那样,您提供了 credentials/api 键来发出该请求。

我的猜测是 mlab 不允许 CORS 的意图是阻止你这样做。您应该 永远不要 将您的私人 API 密钥放在 html 中以托管在网页上,因为通过阅读源代码可以轻松访问它。然后有人可以直接访问您的 mongodb.

相反,您应该创建一个 server-side 应用程序(节点,或... ** 不管什么 **),它公开一个 api 您在同一域(或您提供的域)上控制的允许通过 CORS)。


至于 "preflight" 请求,如果您查看 chrome 调试工具,您应该会看到使用 "OPTIONS" 方法发出的额外请求。这是 chrome(和大多数其他 http 客户端)首先发送到托管在不同域上的服务器的请求。它正在寻找 Access-Control-Allow-Origin header 以确定是否允许发出请求。非常有趣的东西,如果你有时间深入研究的话。

据推测,远程 API 根本不响应 pre-flight 对 GET 调用的请求(因为它不应该这样做)。

您的代码正在触发 pre-flight 请求,因为它是 non-simple。这是由于您添加了 Content-type: application/json header。请求 Content-type header 用于指示请求负载格式。因为它是 GET,所以没有负载。

试试这个...

$.getJSON('https://api.mlab.com/api/1/databases/taskmanager/collections/tasks', {
  apiKey: apiKey
}).done(function(data) {
  console.log(data)
}).fail(function() {
  console.log('FAIL')
})