简体   繁体   中英

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

I am using Apple's new CloudKit JS reference and sample code to build a simple CRUD app. Before I can even get to CRUD however I am being stopped by Apple authentication.

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>

Including div id="apple-sign-in-button" and span id="username" got rid of all errors except:

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

Any mention of this error anywhere else usually has it tied to SMTP or FTP. Any idea what is going on?

The CloudKit.js library is a wrapper around the CloudKit Web Services, and its documentation states that an HTTP 421 happens when a request was called that required authentication, but the user was not logged in.

This is expected as your app will likely need to determine if a user is logged in and, if not, show the appropriate Sign In button. The CloudKit Catalog example's section on Authentication shows how you can set this up by calling container.setUpAuth() , which will check for a user and render the Sign In button if none is detected. It's possible that this is happening in your init.js code, but without seeing it I can't be sure.

I see you have the apple-sign-in-button div on your page. If you're calling the setUpAuth method then you should see the Sign In button rendered inside of it.

Once a user clicks that button and signs in then you can re-issue the original request that was receiving a 421 and should get a valid 200.

Don't forget that if you want to persist the user's CloudKit session you can use auth: { persist: true } when you initialize your Container (see the CloudKit.js docs for more).

You'll also want to ensure you've created an API token in the CloudKit Dashboard for your Container. This is the token you use when you initialize your Container. Check out the WWDC 2015 video on CloudKit JS and Web Services to see a demo of this.

I hope that helps!

UPDATE:

When testing your web application, make sure that you've configured your API Token (using the CloudKit Dashboard) to allow for the domain you're testing with (eg localhost). This was originally Sam's problem but localhost is now a supported domain for API tokens in the Development Environment.

Copying Dave Browning's comment to his answer out as a full-blown answer since that seems to be the issue for me:

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 (eg foo.com) then it should resolve your issue for now

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM