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 &.
Related
I cannot seem to console.log each HTTP POST request's responseText when batching my HTTP POST's using a for loop.
As briefly as I can possibly explain. I am using the for loop to take individual user information and batch users in groups of 99. Once that criteria is met, I build the POST request in JSON, and send it. Then repeat in batches of 99 until all users have been accounted for.
My issue is that I am ONLY getting responseText from the last batch, that is, from the last POST request made. I have tried a number of things, including adding/appending the responseText to a global variable (E.g. var responseString ="";, but am still ONLY getting the last POST's response information...
I'd like to get each batch's responseText and am happy to have them logged individually, or all in the same string... I just need access to this information, in some way. Any help would be appreciated. Here is the code i have going right now:
var responseString = "";
function sendPushNotification(tokens) {
var pageSelecterRadioButton = document.querySelector(
'input[name="page_selecter"]:checked'
);
var pageSelected = pageSelecterRadioButton.value;
var listComplete = tokens.length;
var batchCounter = 0;
var batchMaker = 0;
var batchRecipients;
var batchNumber = 0;
var recipientsProcessed = 0;
for (batchMaker = 0; batchMaker < 99; batchMaker++) {
batchRecipients =
tokens[recipientsProcessed] + `","` + batchRecipients;
console.log(
"Building Batch #" + (batchNumber + 1));
batchCounter++;
recipientsProcessed++;
if (batchCounter == 99 || listComplete == recipientsProcessed) {
// console.log(`"` + batchRecipients.slice(0, -11));
batchNumber++;
var subjectLineRaw = document.getElementById("subject").value;
var messageBodyRaw = document.getElementById("body").value;
const subjectLine = subjectLineRaw.replace(/(\r\n|\n|\r)/gm, " ").replace(/ "/gm, ' “').replace(/" /gm, '” ').replace(/^"/gm, "“")
.replace(/"$/gm, "”");
const messageBody = messageBodyRaw.replace(/(\r\n|\n|\r)/gm, " ").replace(/ "/gm, ' “').replace(/" /gm, '” ').replace(/^"/gm, "“")
.replace(/"$/gm, "”");;
var data =
`{
"to": ["` +
batchRecipients.slice(0, -11) +
`],
"title": "` +
subjectLine +
`",
"body": "` +
messageBody +
`",
"sound": "default",
"data": {"event": "` +
pageSelected +
`"}
}`;
var xhr = new XMLHttpRequest();
var url =
"https://api_server_for_sending_push_notifications.com";
xhr.open("POST", url);
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("content-type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status == 200 ) {
responseString += xhr.responseText;
}
};
console.log(data);
console.log(xhr);
xhr.send(data);
console.log(
"Push Notification POST batch #" + batchNumber + "complete!"
);
batchCounter = 2;
batchMaker = 0;
var batchRecipients = " ";
}
if (listComplete + 1 == recipientsProcessed) {
console.log("Awaiting Server Response...");
setTimeout(function () {
btn.classList.remove("button--loading");
}, 3000);
setTimeout(function () {
alert(recipientsProcessed - 1 + " Push Notifications Sent!");
console.log("Complete! Here is the Server Response...");
}, 3500);
submitButton.disabled = false;
console.log(responseString);
break;
}
}
}
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;
When I send this request using soap envelope over http UA asks for credentials. When I send it over https UA doesn't ask for credentials but returns 401 error.
I need user to enter credentials this way.
var wsUrl = config.identityServerURL + "/services/RemoteUserStoreManagerService.RemoteUserStoreManagerServiceHttpsSoap11Endpoint/";
namesToEnable.forEach(function (name) {
var soapRequest = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.ws.um.carbon.wso2.org" xmlns:xsd="http://common.mgt.user.carbon.wso2.org/xsd"> ' +
'<soapenv:Header/> ' +
'<soapenv:Body> ' +
'<ser:setUserClaimValues>' +
'<ser:userName>' + name + '</ser:userName>' +
'<ser:claims> <!--Optional:--> ' +
'<xsd:claimURI>http://wso2.org/claims/identity/accountDisabled</xsd:claimURI> <!--Optional:--> ' +
'<xsd:value>false</xsd:value> </ser:claims> <!--Optional:--> ' +
'<ser:profileName></ser:profileName> </ser:setUserClaimValues> ' +
'</soapenv:Body></soapenv:Envelope>';
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('POST',
wsUrl, true);
var sr = soapRequest;
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status > 200 < 300) {
console.log('DONE');
sap.ui.getCore().byId("DialogOnEnableUser").close();
sap.m.MessageToast.show("User successfully enabled", {duration: 1000});
} else {
console.log('ERR soap req');
}
}
};
// Send the POST request
xmlhttp.withCredentials = true;
xmlhttp.setRequestHeader("SOAPAction", "urn:setUserClaimValues");
xmlhttp.setRequestHeader('Content-Type', 'text/xml');
xmlhttp.send(sr);
Sounds to me like a security restriction due to the ongoing fight on web lack of secure connectivity
https://superuser.com/questions/770897/firefox-does-not-prompt-for-password-for-http-authenticated-sites-how-to-make-i
I would try it with other browsers to discard it first.
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.
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.