加载资源失败:服务器响应状态为 421(错误请求)

Failed to load resource: the server responded with a status of 421 (Bad Request)

我正在使用 Apple 的新 CloudKit JS 参考和示例代码来构建一个简单的 CRUD 应用程序。在我什至可以到达 CRUD 之前,我被 Apple 身份验证阻止了。

index.html
<html>
<body>

<div id="apple-sign-in-button">Sign in
       <span id="username"></span>
</div>

<script>
    /*
     * Initialize the global objects we will need.
     */
    if(typeof CKCatalog === 'undefined') {
        CKCatalog = {};
    }

    if(typeof CKCatalog.tabs === 'undefined') {
        CKCatalog.tabs = {
            'readme': [{}],
            'not-found': [{}]
        };
    }
</script>

<script src="js/init.js"></script>
<script src="js/cloudkit-code-samples/authentication.js"></script>
<script>
    window.addEventListener('cloudkitloaded',CKCatalog.init);
</script>
<script async src="https://cdn.apple-cloudkit.com/ck/1/cloudkit.js">    </script>

</body>

包括 div id="apple-sign-in-button" 和 span id="username" 消除了所有错误,除了:

加载资源失败:服务器响应状态为 421(错误请求)。

在其他任何地方提及此错误通常都与 SMTP 或 FTP 相关。知道发生了什么事吗?

CloudKit.js 库是 CloudKit Web 服务的包装器,并且 its documentation 指出当调用需要身份验证的请求时会发生 HTTP 421,但用户是未登录。

这是预期的,因为您的应用可能需要确定用户是否已登录,如果没有,则显示相应的登录按钮。 CloudKit Catalog example's section on Authentication 显示了如何通过调用 container.setUpAuth() 进行设置,它将检查用户并在检测到 none 时呈现登录按钮。这可能发生在您的 init.js 代码中,但没有看到它我不能确定。

我看到你的页面上有 apple-sign-in-button div。如果您正在调用 setUpAuth 方法,那么您应该会看到在其中呈现的登录按钮。

一旦用户单击该按钮并登录,您就可以重新发出收到 421 的原始请求,并且应该得到有效的 200。

不要忘记,如果您想保留用户的 CloudKit 会话,您可以在初始化容器时使用 auth: { persist: true }(有关更多信息,请参阅 CloudKit.js 文档)。

您还需要确保已在 CloudKit 仪表板中为您的容器创建了一个 API 令牌。这是您在初始化容器时使用的令牌。查看有关 CloudKit JS 和 Web 服务的 WWDC 2015 视频,观看相关演示。

希望对您有所帮助!

更新:

在测试您的 Web 应用程序时,请确保您已配置 API 令牌(使用 CloudKit 仪表板)以允许您正在测试的域(例如本地主机)。这最初是 Sam 的问题,但 localhost 现在是开发环境中 API 令牌的受支持域。

将 Dave Browning 的评论复制到他的答案中作为一个完整的答案,因为这似乎是我的问题:

The localhost is the issue. localhost is not currently supported as a valid domain with CloudKit Web Services, but it's also a known bug. If you use a tool to map a local server to a fake domain (e.g. foo.com) then it should resolve your issue for now