[GIS] How to add item to the ArcGIS Portal with the portal API

arcgis-javascript-apiarcgis-portal

I'm trying to add/update an item back to the ArcGIS Portal using the portal API, in much the same way as you would when doing 'Configure Application'. I am trying to use the update item call to send an item back to the server via POST.

In Chrome I am getting the error "Origin localhost:53657 is not allowed by Access-Control-Allow-Origin". In IE I get the error "Access Denied" and FF nothing happens.

I understand about cross origin, but I thought the ESRI server must support it otherwise how would we make this post? I can't use jsonp since this does not support post

Edit: If I try to do AddItem I get the error:
XMLHttpRequest cannot load https://yyy.maps.arcgis.com/sharing/content/users/yyy_wilton_d/addItem. Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers.

Can anyone see what I am doing wrong? Does anybody have a sample? Or how can I check that the ESRI server is set up to support CORS?

esri.config.defaults.io.corsEnabledServers.push("https://yyy.maps.arcgis.com/");
var apiID  = 07d5de8305cf47c99057ca1336e2yyy
var xhrArgs = {
    url: 'https://yyy.maps.arcgis.com/rest/content/users/yyy_wilton_d/items/' + apiID  + '/update',
    token: this.token,
    overwrite: true,
    content: cont,
    text: dojo.toJson(cont),
    handleAs: "json",
    load: function (data) {
        debugger;
    },
    error: function (error) {
        debugger;
    }
};
dojo.xhrPost(xhrArgs);

Best Answer

I think I've found the solution to this issue. The code works fine* if security is disabled in chrome (Chrome.exe --disable-web-security), which means my code is ok. The error seems to say that the server will not accept the header X-Requested-With which is added by default by dojo xhrPost. Therefore I set the header value to null (as suggested by ESRI support) and the request went through fine in Chrome/FF

I have submitted a request to ESRI to get the header added to the server as suggested by this exchange

Edit: it works in IE9 using dojo.xhrPost so long as the site and ArcGIS online server are running on the same protocol, most likely https.

*Looking at the way "configure application" works in fiddler on ArcGIS online site they do not use 'update item' but instead 'add item' with overwrite = true. In order to get the webmap template and its associated data use the code getTemplate code listed below.

        addItem: function (item, itemData) {
            var cont = item;
            if (!cont) cont = {};
            cont.f = "json";
            cont.token = this.token;
            cont.text = dojo.toJson(itemData);
            cont.overwrite = true;
            cont.item = cont.id;
            cont.itemType = "text";
            var xhrArgs = {
                url: 'https://xxx.maps.arcgis.com/sharing/content/users/xxx_wilton_d/addItem',
                token: this.token,
                content: cont,
                handleAs: "text",
                headers: {
                    "X-Requested-With": null
                },
                load: function (data) {
                    data = dojo.fromJson(data);
                    if (data.success == true) {
                        console.log('Updated item data!');
                    } else { console.error('Failed to update item data!'); }
                },
                error: function (error) {
                    console.error(error);
                }
            };
            dojo.xhrPost(xhrArgs);
        },

         getTemplate: function () {
            //gets the application which has been created from our template and it's configuration data
            var urlObject = esri.urlToObject(document.location.href);
            if (configOptions.appid || (urlObject.query && urlObject.query.appid)) {
                var appId = configOptions.appid || urlObject.query.appid;
                var d1 = this.getItem("rest/content/items/" + appId, null);
                var d2 = this.getItem("rest/content/items/" + appId + "/data", null);
                var dList = new dojo.DeferredList([d1, d2]);
                dList.then(dojo.hitch(this, function (response) {
                    //update the item data
                    var item = (response[0][1]);
                    var itemData = response[1][1];
                    //assume a small change has been made to the item or its data. Save it back to the server
                    this.addItem(item, itemData);
                }));
            }
        },