05-02-2016 12:07 PM - edited 03-01-2019 04:28 AM
I am trying to access the always-on APIC-EM sandbox API using my webserver and javascript. I have already done the python based learning labs and didn't have much issue with it.
Scenario:
I have a locally hosted nodejs server. I am using xmlHttpRequest (the nodejs version xhr actually) and I can run a GET command no problem. However, since V1 and the new ticketing system, I need to be able to POST the username/password so that I can get the ticket and run the GET commands that I want (network device discovery etc).
Problem:
APIC-EM doesn't seem to recognize the header content type of 'application/json' when I POST (it does with GET, no problem). It returns an error of: "error code": "unknown", "message": "Content-type: 'text/plain;charset=UTF-8' not supported"
Here is my code:
var json_text = '{ "username": "admin","password": "C!sc0123" }';
var ticket_json = JSON.parse(json_text);
var apicem_ip = "sandboxapic.cisco.com:9443";
var apic_url = 'https://'+apicem_ip+'/api/v1/ticket';
//- var xmlHTTP = new XMLHttpRequest();
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
xhr.open('POST',apic_url,false);
xhr.responseType = 'JSON';
xhr.setRequestHeader = ('content-type', 'application/json');
xhr.send(JSON.stringify(ticket_json));
app.locals.apic_nd = xhr.responseText;
Lines 6 and 12 are nodejs specific as XMLHttpRequest doesn't exist natively in nodejs. I don't think that is a problem because I can successfully use GET and receive a response from the sandbox controller. Line 12 is just setting a global variable to be called in my HTML file (which is where I view the responses and errors from the sandbox controller).
Things I've tried, I tried to send just a plain JSON object on line 11 (without the stringify function which converts it into a string), but that doesn't work in Java Script and I believe that that is not how the python API works either (it is a string as well). I also changed line 10 to 'text/json' as well, no luck.
Why am I trying to do this?
I already have a way to view the controller data via a shell using python, I would like to call the APIs and see the same data via a browser. I figured JavaScript would be the easiest way but ran into the above issue.
Any help would be appreciated.
07-17-2016 06:13 AM
My understanding is that cors prevents HTTP requests from running in browser. I worked around this by sending info to nodejs server and sending request from there. Not sure how else to do it.
07-17-2016 08:40 AM
thanks Joshua. I think I have the same problem.
So basically you using a proxy in between to send the request on behalf and then return the response back.
Sounds like we are hacking our way through it.
I am using a local machine which runs the scripts and then passing it to my locally run IIS server and getting output.
I also noticed that some timeout needs to be set to get response. If I run the alerts too fast i dont get an output.
Here's how I'm setting a little timeout for the script to get the information from the server. Are you able to get the info immediately? So far I have been able to run some codes already using PUT and GET. But I am now learning how to create a Java Application to access this information instead of using Javascript.
setTimeout(tst, 3000);
function tst () {
var data = JSON.parse(xmlHttp.responseText);
document.getElementById("demo").innerHTML = "The Ticket number is " + data.response.serviceTicket;
alert(data.version);
}
07-17-2016 09:31 AM
Nodejs is asynchronous so the timeouts and dealing with hangups are explicit in the architecture. I.e., it will call the request, then move on to other code, and then come back to the request as soon as there is a response.
I agree that using a back end server for requests is a bit of a work around, but then again, I don't understand cors and the security issues that come with. I doubt using a back end server is any more secure though.
07-17-2016 01:44 PM
Thanks. I get it. Just tried with a Java Application and none of the cors issues. It seems to be a JS specific issue. Even the timeout is not necessary.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide