Missing Authorization in CORS headers of Cloud API

Hi @Peli,

Sorry, I think the error we noticed is that our API should give a clearer error message when the wrong headers are sent with a file upload. Here’s a file uploader page I mocked up, I believe this should be closer:

<!DOCTYPE html>
<html>
<head>
    <title></title>

    <style>
        form {
            width: 95%;
            height: 100px;
            border: 1px solid #ccc;
        }

        progress {
            width: 95%;
        }

    </style>

</head>
<body>

<form enctype="multipart/form-data">
    <div>
        <input name="file" type="file"/>
    </div>
    <div>
        <input id="btnUpload" type="button" value="Upload"/>
    </div>
</form>
<progress></progress>

<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>

    var Page = {
        startup: function () {
            $('#btnUpload').attr('disabled', false);
            $('#btnUpload').click(Page.onButtonClick);

            $('progress').attr({value: 0, max: 10});
        },
        onButtonClick: function () {
            $('#btnUpload').attr('disabled', true);
            $('progress').attr({value: 1, max: 10});
            Page.uploadFile();
        },

        uploadFile: function () {
            var formData = new FormData($('form')[0]);

            var a = $.ajax({
                url: "https://api.spark.io/v1/devices/<DEVICE ID>",
                type: "POST",
                data: formData,
                xhr: function () {  // Custom XMLHttpRequest
                    var myXhr = $.ajaxSettings.xhr();
                    if (myXhr.upload) { // Check if upload property exists
                        myXhr.upload.addEventListener('progress', Page.onProgress, false); // For handling the progress of the upload
                    }
                    return myXhr;
                },
                cache: false,
                contentType: false,
                processData: false
            });

            a.done(Page.onUploadDone);
            a.fail(Page.onUploadFailed);
        },

        onUploadDone: function () {
            console.log('upload done!');
            $('#btnUpload').attr('disabled', false);
        },
        onUploadFailed: function () {
            console.error('upload failed ! ', arguments);
            $('#btnUpload').attr('disabled', false);
        },

        onProgress: function (e) {
            //http://stackoverflow.com/questions/166221/how-can-i-upload-files-asynchronously-with-jquery
            if (e.lengthComputable) {
                $('progress').attr({value: e.loaded, max: e.total});
            }
        }

    };

    Page.startup();
</script>

</body>
</html>
1 Like

Thanks for the sample. 2 minor issues:

type="POST" should be type="PUT"

and missing authorization headers.

1 Like

Also, the file needs to explicitely include “application.h” (unlike in spark build)

#include "application.h"
1 Like

The return value does not match the docs. A succesfull PUT (200) returns the following JSON in the response body – which does not match the docs:

{
  "cmd": "Event",
  "name": "Update",
  "message": "Update started"
}

Thank you for all the help. I was able to build a simple IDE for spark in TouchDevelop. You can try it out at http://tdev.ly/hugo !

2 Likes