I'm trying to consume a SOAP (.net) WebService with JavaScript but the responseText and the responseXML are null. I tried running in another browser(chrome, firefox, IE) but that didn't solve it.
function MButton1Click(event) {
sendDataAsXML_SOAP();
}
function sendDataAsXML_SOAP() {
var req_params = "",
url = "",
number = 0,
type = "";
/* Configure Parameters */
url = "http://wp.art.br/FriendNet/Principal.asmx";
var user = document.getElementById("MTextArea1").value;
var ajaxRequest;
req_params = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
req_params = req_params + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema- instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
req_params = req_params + " <soap:Body>";
req_params = req_params + " <TesteDeTexto xmlns=\"http://tempuri.org/\">";
req_params = req_params + " <pTexto>" + user + "</pTexto>";
req_params = req_params + " </TesteDeTexto>";
req_params = req_params + " </soap:Body>";
req_params = req_params + "</soap:Envelope>";
/* Send XML/SOAP Request To Web Service Using Browser's Javascript DOM */
var xmlHTTP;
if (window.XMLHttpRequest) {
xmlHTTP = new window.XMLHttpRequest; //For browsers other than ie
} else {
try {
xmlHTTP = new ActiveXObject("MSXML2.XMLHTTP.3.0"); //for ie
} catch (ex) {}
}
xmlHTTP.open("POST", url, true);
xmlHTTP.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHTTP.setRequestHeader("SOAPAction", "http://tempuri.org/TesteDeTexto");
xmlHTTP.onreadystatechange = receiveXML_SOAPData;
xmlHTTP.send(req_params);
}
function receiveXML_SOAPData() {
if (ajax_request.readyState == 4) {
if (ajax_request.status == 200 || ajax_request.status == 0) {
/* Parse The Response Data */
alert(ajax_request.responseText);
alert(ajax_request.responseXML);
alert("sucesso");
}
}
}
You try to use a ajax_request in your receiveXML_SOAPData function which is undefined. You should have gotten an exception from that, check your error console.
The ajaxrequest variable in the sendDataAsXML_SOAP function is a) not used and b) local to that function - it would not work.
Use the this keyword in the receiveXML_SOAPData function to reference the XHR object instead.
Related
I am new to APIs and I want to add the USDA Nutrients database api to my website. I want the user to be able to search for the food,select one of the appeared results and see its' nutrition information.
How can I do this in plain JS? I've created a search bar in my website and JS takes the input and requests the data from the USDA api.
var apiKey = '';
var q = "eggs";
var url = "http://api.nal.usda.gov/ndb/search/?format=json&q=" + q + "&sort=n" + "&max=25" + "&offset=0" + "&api_key=" + apiKey;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
var data = JSON.parse(this.responseText);
document.querySelector("#usdaResults").innerHTML = data.body;
}
};
xhr.send();
I want first to present to the user a list of the results of what they searched. Then after they click the food, I want to present its' nutritional information(protein etc).
EDIT: When a user searches a food, I want to display the "group" , "name"and "manu" of all available results. At the same time,when a user wants to see the nutrition information for a specific food of those listed, I want to get its' "ndbno" number and look into the USDA database for it so I can display the data after. Same way as displayed in the official website: https://ndb.nal.usda.gov/ndb/search/list?SYNCHRONIZER_TOKEN=c91f87b5-59c8-47e0-b7dc-65b3c067b7ff&SYNCHRONIZER_URI=%2Fndb%2Fsearch%2Flist&qt=&qlookup=egg+potato&ds=&manu=
EDIT2: I'm getting this error now.
var apiKey = '';
var q = document.getElementById('search').value;
var url = "http://api.nal.usda.gov/ndb/search/?format=json&q=" + q + "&sort=n" + "&max=25" + "&offset=0" + "&api_key=" + apiKey;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
function getData() {
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
var data = JSON.parse(this.responseText);
if (data && data.list && data.list.item) {
var html = "";
data.list.item.map(item => {
let string = "<p>Name: " + item.name + " Manu: " + item.manu + " Group: " + item.group + "<p>";
html += string;
})
}
document.querySelector("#usdaResults").innerHTML = html;
}
else {
console.log("Error", xhr.statusText);
}
}
xhr.send();
}
HTML:
<section class="usda">
<h1>USDA Nutrients Database</h1>
<form id="search">
<input type="text" placeholder="Search.." name="search">
<button type="button" onclick="getData();">Search</button>
</form>
<div id="usdaResults"></div>
</section>
So, it may be that there are errors with your XHR call - however we can catch and log those errors. You want to open your developer tools in your browser (usually right click > developer tools) to look at the JS logs.
I'm getting: VM131:20 GET http://api.nal.usda.gov/ndb/search/?format=json&q=eggs&sort=n&max=25&offset=0&api_key= 403 (Forbidden)
But that's because I have no API Key. If you do not, you'll need to get an API key from them.
I have grabbed some code from another SO post, here:
var apiKey = '';
var q = "eggs";
var url = "http://api.nal.usda.gov/ndb/search/?format=json&q=" + q + "&sort=n" + "&max=25" + "&offset=0" + "&api_key=" + apiKey;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function (oEvent) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(xhr.responseText)
} else {
console.log("Error", xhr.statusText);
}
}
};
xhr.send();
Reference:
XMLHttpRequest (Ajax) Error
EDIT:
For the response, once you have parsed the JSON - you can get all the available name, group and manu of the data as so - I've output the details in tags, and this is untested - so maybe incorrect, but this is more for pseudo code.
var data = JSON.parse(this.responseText);
//Assuming data is valid!
if (data && data.list && data.list.item) {
var html = "";
data.list.item.map(item => {
let string = "<p>Name: " + item.name + " Manu: " + item.manu + " Group: " + item.group + "<p>";
html += string;
})
}
document.querySelector("#usdaResults").innerHTML = html;
I'm trying to create a proxy JS so every request to external resource will be proxied like XHR or any other resource.
so for XHR request i manage to do it with this code:
if(window.XMLHttpRequest)
{
var XMLHttpRequest = window.XMLHttpRequest;
var startTracing = function () {
XMLHttpRequest.prototype.uniqueID = function() {
// each XMLHttpRequest gets assigned a unique ID and memorizes it
// in the "uniqueIDMemo" property
if (!this.uniqueIDMemo) {
this.uniqueIDMemo = Math.floor(Math.random() * 1000);
}
return this.uniqueIDMemo;
}
// backup original "open" function reference
XMLHttpRequest.prototype.oldOpen = XMLHttpRequest.prototype.open;
var newOpen = function(method, url, async, user, password) {
//console.log(url);//new
if (url.includes("somesample")) {
//Debug Only
/*console.log("[" + this.uniqueID() + "] intercepted open (" +
method + " , " +
url + " , " +
async + " , " +
user + " , " +
password + ")");*/
urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(url);
hostname = urlParts[1]; // www.example.com
path = urlParts[2]; // /path/to/somwhere
proxyprefix = "http://myproxy.com/xhr.php?url="
fullurl = "http://" + hostname + path;
rewrittenUrl = proxyprefix + btoa(encodeURIComponent(fullurl));
url = rewrittenUrl;
}
this.oldOpen(method, url, async, user, password);
}
XMLHttpRequest.prototype.open = newOpen;
// backup original "send" function reference
XMLHttpRequest.prototype.oldSend = XMLHttpRequest.prototype.send;
var newSend = function(a) {
//console.log("[" + this.uniqueID() + "] intercepted send (" + a + ")");
var xhr = this;
var onload = function() {
/*console.log("[" + xhr.uniqueID() + "] intercepted load: " +
xhr.status +
" " + xhr.responseText);*/
};
var onerror = function() {
/* console.log("[" + xhr.uniqueID() + "] intercepted error: " +
xhr.status);*/
};
xhr.addEventListener("load", onload, false);
xhr.addEventListener("error", onerror, false);
this.oldSend(a);
}
XMLHttpRequest.prototype.send = newSend;
}
startTracing();
}
else if (window.ActiveXObject) {
var ActualActiveXObject = ActiveXObject;
var ActiveXObject = function(progid) {
var ax = new ActualActiveXObject(progid);
if (progid.toLowerCase() == "msxml2.xmlhttp") {
var o = {
_ax: ax,
_status: "fake",
responseText: "",
responseXml: null,
readyState: 0,
status: 0,
statusText: 0,
onReadyStateChange: null
};
o._onReadyStateChange = function() {
var self = o;
return function() {
self.readyState = self._ax.readyState;
if (self.readyState == 4) {
self.responseText = self._ax.responseText;
self.responseXml = self._ax.responseXml;
self.status = self._ax.status;
self.statusText = self._ax.statusText;
}
if (self.onReadyStateChange) self.onReadyStateChange();
}
}();
o.open = function(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword) {
/*console.log("intercepted open (" +
bstrMethod + " , " +
bstrUrl + " , " +
varAsync + " , " +
bstrUser + " , " +
bstrPassword + ")");*/
varAsync = (varAsync !== false);
this._ax.onReadyStateChange = this._onReadyStateChange
return this._ax.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);
};
o.send = function(varBody) {
return this._ax.send(varBody);
};
}
else
var o = ax;
return o;
}
}
and its working fine.
and because i have got some js that manipulate the dom and adds elements i need to intercept that to.
so i started by rewriting appendChild with that code:
window.callbackFunc = function(elem, args) {
//console.log(elem);
for (var key in elem) {
if (elem.hasOwnProperty(key) && elem[key].src)
{
elem[key].src = "http://myptoxy/proxy.php?u=" +encodeURIComponent(elem[key].src);
}
}
}
window.f = Element.prototype.appendChild;
Element.prototype.appendChild = function() {
window.callbackFunc.call(this, arguments);
return window.f.apply(this, arguments);
};
and thats also working well but i encounter a problem with createlement.
some js code on my site creates an iframe with src that i'm unable to intercept with this code:
document.createElement = function(create) {
return function() {
var ret = create.apply(this, arguments);
//console.log(ret);
for (var key in ret) {
if (ret.hasOwnProperty(key) && ret[key].src) {
ret[key].src = "http://myproxy.com/proxy.php?u=" + encodeURIComponent(elem[key].src);
}
}
return ret;
};
}(document.createElement)
I mean I can intercept the creation but the attributes are empty obviously the script adds the attribute after the element creation)
I tried to use MutationObserver but with no luck...
Any help?
Another approach to the entire problem will be great!
I am writing a small Cordova (PhoneGap) app. that is sending an image from a file input - using a post method. It works fine in my Android device, but fails in both broswer and Ripple emulator. Here is the code:
function queryImageByData(dataURL) {
var imgType = dataURL.substring(5, dataURL.indexOf(";"));
var imgExt = imgType.split("/")[1];
var imgData = atob(dataURL.substring(dataURL.indexOf(",") + 1));
var filenameTimestamp = (new Date().getTime());
var separator = "----------12345-multipart-boundary-" + filenameTimestamp;
var formData = "--" + separator + "\r\n" +
"Content-Disposition: file; name=\"file\"; filename=\"snapshot_" + filenameTimestamp + "." + imgExt + "\"\r\n" +
"Content-Type: " + imgType + "\r\nContent-Transfer-Encoding: base64" + "\r\n\r\n" + imgData + "\r\n--" + separator + "\r\n";
var xhr = new XMLHttpRequest();
xhr.sendAsBinary = function (data) {
var arrb = new ArrayBuffer(data.length);
var ui8a = new Uint8Array(arrb, 0);
for (var i = 0; i < data.length; i++) {
ui8a[i] = (data.charCodeAt(i) & 0xff);
}
var blob = new Blob([arrb]);
this.send(blob);
};
xhr.open("POST", "https:/my_endpoint_here", true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
parseResult(xhr.responseText);
}
else {
onFailedResponse(xhr.responseText);
}
}
};
xhr.setRequestHeader("Content-type", "multipart/form-data; boundary=" + separator);
xhr.sendAsBinary(formData);
}
The error I get is:
Error: MultipartParser.end(): stream ended unexpectedly: state = HEADER_FIELD_START
at MultipartParser.end
EDIT:
I have a problem also with a get method. It fails on Ripple/Browser but runs OK on the device. here is some sample code:
var url = document.getElementById("urlInput").value;
var query = "my_url_here";
var jqxhr = $.ajax(query)
.done(function (data) {
alert("success" + data);
})
.fail(function (data) {
alert("error" + data);
})
Well I found the core issue, which cross domain calls.
The browsers do not allow it, and apperently so does Ripple emulator,
but mobile devices do allow it.
Now I just need to figure out how to make it work using CORS.
In index.html under body tag:
+ -
and under <head><script type="text/javascript">:
var url = "get.php";
function ajaxRequest()
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
var jsondata = eval("(" + xmlhttp.responseText + ")"); //retrieve result as an JavaScript object
document.getElementById("y").innerHTML = jsondata.y;
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function setTempInc()
{
var oldUrl = url;
url = url + "9001" + jsondata.y;
ajaxRequest();
url = oldUrl;
}
I don't understand where the problem is. url is a string and jsondata.y is a int but the script doesn't work!
This function does, though:
function setMode(val)
{
var oldUrl = url;
url = url + "91" + val + "000";
ajaxRequest();
url = oldUrl;
}
I would think that
var jsondata = eval("(" + xmlhttp.responseText + ")");
is not available to be called at
url = url + "9001" + jsondata.y;
as it is only defined inside the ajaxRequest function's scope.
Set variables outside functions, to use as a global variable!
This probably will work:
(function() {
var url = "get.php";
var oldUrl = '';
var jsondata = '';
function ajaxRequest()
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
jsondata = eval("("+xmlhttp.responseText+")"); //retrieve result as an JavaScript object
document.getElementById("y").innerHTML = jsondata.y;
}
}
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
function setTempInc()
{
oldUrl = url;
url = url + "9001" + jsondata.y;
ajaxRequest();
url = oldUrl;
}
})();
Added Closure to avoid common security problems
Receiving http 403 response error when trying to get a
request token.
I've checked my base string's singing process, and that's proper. If
I use the default keys on the Twitter dev site, it generates the same
result as they list on the site, so i'm pretty sure that's okay.
Any insight would be much appreciated!
var reqURL = 'https://api.twitter.com/oauth/request_token';
var reqNonce = getNonce();
var reqTimeStamp = getTimeStamp();
var reqSignatureMethod = 'HMAC-SHA1';
var reqOauthVersion = '1.0';
var reqConsumerKey = 'ySBPkqxaRlheQKFwejMpqg';
var reqConsumerSecret = '______________&' // note the & at the end..
var reqCallback = 'http%3A%2F%2Flocalhost%3A3005%2Fthe_dance%2Fprocess_callback%3Fservice_provider_id%3D11'
var reqQuery = 'oauth_callback=' + reqCallback + '&oauth_consumer_key=' + reqConsumerKey + '&oauth_nonce=' + reqNonce + '&oauth_signature_method=' + reqSignatureMethod + '&oauth_timestamp=' + reqTimeStamp + '&oauth_version=' + reqOauthVersion;
var reqBaseString = 'POST&' + reqURL + '&' + encodeURIComponent(reqQuery);
var reqSignature = b64_hmac_sha1(reqConsumerSecret, reqBaseString);
var reqSignature = reqSignature + '=';
var request = new XMLHttpRequest();
request.onreadystatechange = function(data) {
if (request.readyState == 4) {
// Good response, got the xml file
if (request.status == 200) {
alert ('good response');
}
}
};
// alert (reqURL);
// alert (reqBaseString);
var oauthParams = encodeURIComponent("OAuth oauth_callback=\"" + reqCallback + "\",oauth_consumer_key=\"" + reqConsumerKey + "\",oauth_nonce=\"" + reqNonce + "\",oauth_signature_method=\"" + reqSignatureMethod + "\",oauth_timestamp=\"" + reqTimeStamp + "\",oauth_version=\"1.0\",oauth_signature=\"" + reqSignature + "\"");
request.open("POST", reqURL, true);
request.setRequestHeader("Accept", "text/plain, */*");
request.setRequestHeader("Connection", "Keep-Alive");
request.setRequestHeader("Authorization", oauthParams);
request.send();
What I have found to be immensely helpful is to just get the raw HTTP request that does work with the Netflix OAuth Test that cnauroth suggested and then compare it to what you are sending with this code snippet here. OAuth is tricky and not fun so if you can just diff the two requests you should be able to find some improper encoding or a misplaced &.