I'm very new to javascript and web programming in general and I need some help with this. I have an HTTP request that I need to send through javascript and get need to store the output in a variable. I tried using just the call url:
https://api.fantasydata.net/nfl/v2/JSON/PlayerSeasonStats/2015
But it returns an authentication error because I didn't send my API key and it doesn't show me how to do it just in the URL. The API key is listed as a header and not a paramater and I'm not sure what to do with that. I tried using the XMLHttpRequest() class but I'm not quite sure I understand exactly what it does nor could I get it to work.
The actual HTTP Request
GET https://api.fantasydata.net/nfl/v2/JSON/PlayerSeasonStats/2015 HTTP/1.1
Host: api.fantasydata.net
Ocp-Apim-Subscription-Key: ••••••••••••••••••••••••••••••••
I just need to figure out how to send that request along with the key and how to store the JSON doc it returns as a variable in javascript.
EDIT: This is what I have so far:
function testingAPI(){
var key = "8a1c6a354c884c658ff29a8636fd7c18";
httpGet("https://api.fantasydata.net/nfl/v2/JSON/PlayerSeasonStats/2015",key );
alert(xmlHttp.responseText);
var x = 0;
}
function httpGet(theUrl,key)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
xmlHttp.setRequestHeader("Ocp-Apim-Subscription-Key",key);
xmlHttp.send( null );
return xmlHttp.responseText;
}
Thank you!
If it says the API key is listed as a header, more than likely you need to set it in the headers option of your http request. Normally something like this :
headers: {'Authorization': '[your API key]'}
Here is an example from another Question
$http({method: 'GET', url: '[the-target-url]', headers: {
'Authorization': '[your-api-key]'}
});
Edit : Just saw you wanted to store the response in a variable. In this case I would probably just use AJAX. Something like this :
$.ajax({
type : "GET",
url : "[the-target-url]",
beforeSend: function(xhr){xhr.setRequestHeader('Authorization', '[your-api-key]');},
success : function(result) {
//set your variable to the result
},
error : function(result) {
//handle the error
}
});
I got this from this question and I'm at work so I can't test it at the moment but looks solid
Edit 2: Pretty sure you should be able to use this line :
headers: {'Authorization': '[your API key]'},
instead of the beforeSend line in the first edit. This may be simpler for you
With your own Code and a Slight Change withou jQuery,
function testingAPI(){
var key = "8a1c6a354c884c658ff29a8636fd7c18";
var url = "https://api.fantasydata.net/nfl/v2/JSON/PlayerSeasonStats/2015";
console.log(httpGet(url,key));
}
function httpGet(url,key){
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", url, false );
xmlHttp.setRequestHeader("Ocp-Apim-Subscription-Key",key);
xmlHttp.send(null);
return xmlHttp.responseText;
}
Thank You
**`
U need to have a
send();
Statement.
That way you can send the request to the site server.
`**
Related
i'm doing my baby steps in web-development.
I have a Html+JS(jQuery) Frontend and a C# Backend.
For now i just want a ping-pong request/response.
The JS looks like this :
$(document).ready(function() {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "http://testhttp/", false ); // false for synchronous request
xmlHttp.send();
console.log(xmlHttp.responseText);
});
The C# looks like this
if (!HttpListener.IsSupported)
{
...
}
string[] prefixes = {"http://testhttp/"};
// Create a listener.
HttpListener listener = new HttpListener();
// Add the prefixes.
foreach (string s in prefixes)
{
listener.Prefixes.Add(s);
}
listener.Start();
Console.WriteLine("Listening...");
// Note: The GetContext method blocks while waiting for a request.
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
// Obtain a response object.
HttpListenerResponse response = context.Response;
// Construct a response.
string responseString = "<p> Hello world!</p>";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// Get a response stream and write the response to it.
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer,0,buffer.Length);
// You must close the output stream.
output.Close();
listener.Stop();
The Backend receives the request. However the response will not be transmitted correctly or permission is denied (on Firefox and Chrome).
jquery-3.2.0.min.js:2 Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://testhttp/'.
I read that it might has something to do with the origin of the response and i need to set Access-Control-Allow-Origin. But those attempts failed.
Can someone pls guide me here?
Edit
Based on comments the js looks like this
$(document).ready(function() {
$.ajax({
url: "http://testhttp/",
type: "GET",
crossDomain: true,
dataType: "json",
success: function (response) {
$('#Test').html(response);
},
error: function (xhr, status) {
alert("error");
}
});
});
and in C# backend i added
response.Headers["Access-Control-Allow-Origin"] = "*";
Getting
GET http://testhttp/ net::ERR_CONNECTION_RESET
I use $(document).ajaxSend(...) to dynamically add data (POST args) to some Ajax requests, when necessary.
Adding data works when some datas have been defined in an $.ajax(...) call. But if no data has been defined in the $.ajax setting, my $.ajaxSend can't add data to the settings.
Here is my $.ajaxSend interceptor:
$(document).ajaxSend(function(e, request, settings) {
if(settings.csrfIntention) {
var requestToken = {
intention: settings.csrfIntention,
hash: self.tokens[settings.csrfIntention]
}
if(!settings.data) {
settings.data = '_token=' + encodeURIComponent(JSON.stringify(requestToken));
}
else if(typeof(settings.data) == 'string') {
settings.data += '&_token=' + encodeURIComponent(JSON.stringify(requestToken));
}
else if(!settings.data._token) {
settings.data._token = requestToken;
}
}
});
And an example of $.ajax call that works:
$.ajax({
url: opts.close.url,
method: 'POST',
data: { foo:'bar' },
csrfIntention: 'ajax_close_ticket',
success: function(data) { ... }
});
The $.ajaxSend works and settings.data is set to:
foo=bar&_token=%7B%22intention%22%3A%22ajax_close_ticket%22%2C%22hash%22%3A%22uXV1AeZwm-bZL3KlYER-Dowzzd1QmCmaT6aJFjWLpLY%22%7D
Serverside, I can retrieve the two fields: foo and _token.
Now, if I remove the data object in the $.ajax call, the output of $.ajaxSend seems Ok, too:
_token=%7B%22intention%22%3A%22ajax_close_ticket%22%2C%22hash%22%3A%225cK2WIegwI6u8K_FrxywuauWOo79xvhIcASQrZ9QPZQ%22%7D
Yet, the server don't receive my _token field :(
Another interesting fact: when I have the two fields, the Chromium dev tools under the Network tab displays the two fields under a "Form Data" title. When _token is alone, "Form Data" is replaced by "Request Payload".
Edit: just understood why _token is not interpreted by the server. If no data has been previously set in $.ajax call, jQuery does not add the right Content-Type in HTTP headers, it set it to text/plain instead of application/x-www-form-urlencoded. How can I force jQuery to add this header?
Edit 2: Solution found. Will post an answer to help other people...
I apologize for my bad English
I believe that the solution to his case would be the use of the function "ajaxSetup"
var requestToken = {
intention: settings.csrfIntention,
hash: self.tokens[settings.csrfIntention]
};
$.ajaxSetup({
data : {
_token: requestToken
}
});
this way all your orders took the data as the desire
A simpler approach:
var requestToken = {
intention: settings.csrfIntention,
hash: self.tokens[settings.csrfIntention]
}
var myForm = {};
myForm['_token'] = encodeURIComponent(JSON.stringify(requestToken));
In your ajax call:
myForm['foo'] = 'bar';
$.ajax({
url: opts.close.url,
method: 'POST',
data: myForm,
csrfIntention: 'ajax_close_ticket',
success: function(data) { ... }
});
//This sends foo and _token
Finally I answer my question after only 10 minutes...
In HTTP, the form arguments are sent into the request body, under the headers. The header Content-Type should be present to declare the data type. When this header is set to application/x-www-form-urlencoded, the server will understand that you sent a form and will parse the request body as a GET URL (you know, the foo=bar&key=val format).
jQuery adds this header automatically when you set a data object into the $.ajax call. Then it passes the request to the $.ajaxSend callback, which adds its proper fields.
When no data has been provided in request settings, jQuery do not add an unnecessary Content-Type: x-www-form-urlencoded in the request headers. Then, when you append the request body into your $.ajaxSend callback, jQuery do not check the data again and declares the content as text/plain. The server has nothing to do with text/plain so it does not interpret the body data as form fields.
You can obviously force jQuery to change the header to application/x-www-form-urlencoded, let's take the code of my original post :
if(!settings.data) {
settings.data = '_token=' + encodeURIComponent(JSON.stringify(requestToken));
}
Now add the right header:
if(!settings.data) {
settings.data = '_token=' + encodeURIComponent(JSON.stringify(requestToken));
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
I have been trying for the past couple of days to develop an application for our Lync service at work using the UCWA API from Microsoft (a REST API). To get an application working: I first have to submit it to the API using a POST request to a certain URL. First, I have to authenticate with the server, and I do that by posting a username and a password credential to the API. I then get an access token back which I can use to make further requests to the API by posting the token inside the header of each request. I have been able to get an access token working, but when I try to register the application by posting a HTTP request to https://lyncextws.company.com/ucwa/oauth/v1/applications: Things will start to go wrong.
All this is done through one JavaScript file working with iframes to bypass the Same-origin policy.
This is what my code currently looks like:
<!DOCTYPE html>
<html lang="no">
<head>
<meta charset="UTF-8" />
<title>PresInfoDisp</title>
</head>
<body>
<iframe src="https://lyncextws.company.com/Autodiscover/XFrame/XFrame.html" id="xFrame" style="display: none;"></iframe>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
var access_token;
var stage = 0;
// CONNECT AND AUTHENTICATE WITH LYNC UCWA SERVICE
function connectAndAuthenticate() {
stage = 1;
var request = {
accepts: 'application/json',
type: 'POST',
url: 'https://lyncextws.company.com/WebTicket/oauthtoken',
data: 'grant_type=password&username=alexander#domain.company.com&password=somePassword'
};
document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/WebTicket/oauthtoken');
}
// REQUEST A USER RESOURCE
function getUserResourceAuthRequest() {
stage = 0;
var request = {
accepts: 'application/json',
type: 'GET',
url: 'https://lyncextws.company.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=company.com'
};
document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=company.com');
}
function getUserResource() {
stage = 2;
var request = {
accepts: 'application/json',
type: 'GET',
url: 'https://lyncextws.company.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=company.com',
headers: {Authorization: "Bearer "+access_token}
};
document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=company.com');
}
// REGISTER APPLICATION RESOURCE
function registerApplication() {
stage = 3;
var request = {
accepts: 'application/json',
type: 'POST',
url: 'https://lyncextws.company.com/ucwa/oauth/v1/applications',
headers: {Authorization: "Bearer "+access_token},
data: {'userAgent': 'InfoDisp1', 'endpointId' : '2d9dc28d-4673-4035-825c-feb64be28e4e', 'culture': 'en-US'}
};
document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/ucwa/oauth/v1/applications');
}
// GRAB A LIST OF CONTACTS
function listContacts() {
stage = 4;
var request = {
accepts: 'application/json',
type: 'GET',
url: 'https://lyncextws.company.com/ucwa/oauth/v1/applications',
headers: {Authorization: "Bearer "+access_token}
};
document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/ucwa/v1/applications');
}
this.receiveMessage = function(message) {
switch(stage) {
case 1:
var beforeReplace = message.data.replace("/\\/g", "");
var json = jQuery.parseJSON(beforeReplace);
var json2 = jQuery.parseJSON(json.responseText);
access_token = json2.access_token;
console.log(json2.access_token);
console.log(message);
getUserResource();
break;
case 0:
console.log(message);
connectAndAuthenticate();
break;
case 2:
var beforeReplace = message.data.replace("/\\/g", "");
var json = jQuery.parseJSON(beforeReplace);
var json2 = jQuery.parseJSON(json.responseText);
console.log(json2._links.applications.href);
window.setTimeout(function(){registerApplication()}, 5000);
break;
case 3:
console.log(message);
break;
case 4:
break;
}
};
window.addEventListener('message', this.receiveMessage, false);
$(window).load(function() {
getUserResourceAuthRequest();
//console.log(access_token);
});
</script>
</body>
</html>
When I run this code: The last ajax query returns the error 409: Conflict, when it should be returning 201: Created
This is what my browser (Google Chrome) outputs:
The 401: Unauthorized error is supposed to happen, but the 409 Conflict, should not happen. So here is my question:
Can anyone spot why I get this 409 error instead of the 201 I should be getting?
The example code from Microsoft seems to work fine, but I want to avoid using that as it will take me a very long time to familiarize myself with it.
If there is missing data you need to spot the issue: Let me know in the comments, and i'll provide it!
If you replace
data: {'userAgent': 'InfoDisp1', 'endpointId' : '2d9dc28d-4673-4035-825c-feb64be28e4e', 'culture': 'en-US'}
with a string of that data instead I.E.
data: "{'userAgent': 'InfoDisp1', 'endpointId' : '2d9dc28d-4673-4035-825c-feb64be28e4e', 'culture': 'en-US'}"
it seems that data expects a string and in your example you are passing it a JSON object. Doing that makes your example work for me.
The problem seems to be with your static endpointId.
In their original helper libraries they have a method called generateUUID() which is in GeneralHelper. The best idea would be to use that method, however, if you feel like creating ayour own, go for it. The main point is that each of your application must have different endpointId.
Are you omitting the autodiscovery process for brevity only, or are you really skipping the autodiscovery in your code and assuming the URI where to post the 'create application'?
It seems more the second case to me, and this isn't right:
the URI where to create the application needs to be retrieved from the response of the user resource request (within getUserResource in the code you posted).
You have a link called applications there; its value contains the correct URI where to create the application.
http://ucwa.lync.com/documentation/KeyTasks-CreateApplication
P.S. I post here as well about the endpointId, seen I can't comment above
It is allowed to use the same application's endpointId on different clients. It is absolutely not to be assumed anyway that applications on different clients using the same endpointId will result in the same base application resource URI
I was getting this same problem using curl to experiment with this API, and failed at this same point until I figured out that in that case I needed to set content-type header to json:
curl -v --data "{'userAgent': 'test', 'endpointId': '54321', 'culture':'en-US', 'instanceID':'testinstance'}" --header 'Content-Type: application/json' --header 'Authorization: Bearer cwt=AAEBHAEFAAAAAAA..' 'https://lyncserver.com/ucwa/oauth/v1/applications'
That did the trick!
im trying to create own POST request. Here is my function:
function sendPost(o) {
var h = new XMLHttpRequest();
h.onreadystatechange = requestComplete;
function requestComplete() {
if ( h.readyState === 4 ) {
if ( h.status === 200 ) {
if ( o.done ) {
o.done(h.responseText);
}
} else {
if ( o.fail ) {
o.fail(h.responseText);
}
}
}
}
h.open('POST', o.url, true);
h.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
h.send(o.data);
}
Everything is OK, but im confused, how to set its dataType to script, like in jQuery:
$.ajax({
url: 'someurl.php',
type: 'POST',
dataType: 'script' // <-- how to do this?
});
dataType has very little to do with sending Ajax requests. It is primarily about what jQuery does with the response.
From the documentation:
"script": Evaluates the response as JavaScript and returns it as plain text. Disables caching by appending a query string parameter, "_=[TIMESTAMP]", to the URL unless the cache option is set to true.
So there is some modification to do with sending here.
Take o.data
Get a timestamp from a new Date()
Check (by looking at indexOf('?') if it has a query string already
Append either ? or & to the URL followed by the time stamp
The rest is all about processing the response:
Evaluates the response as JavaScript
So:
eval(h.responseText);
This is all rather nasty though. Generally speaking, if you want to dynamically load a script, you are usually better off doing it by adding a <script> element to a page.
I have a serverside function:
string foo(string input_string);
for example:
foo("bar") returns "baz"
and have wrapped this function into a HTTP server such that:
POST /foo HTTP/1.1
...
bar
will return:
HTTP/1.1 200 OK
...
baz
ie a POST request with the input string as the HTTP Message Body will return the output string as the HTTP Message Body of the 200 OK.
Now in my javascript on the web page I have two functions:
function sendFoo(input_string)
{
??? // should asynchronously start process to POST input_string to server
}
function recvFoo(output_string)
{
...
}
When I call sendFoo I would like the POST to be made asynchronously to the server and later when the response is received I would like recvFoo called (perhaps in another thread or whatever) with the Message Body of the 200 OK.
How do I implement sendFoo above? I am currently using jQuery, but a solution in pure javascript is ok too. (I can also modify the server if need be?)
Solution:
function sendFoo(input_string)
{
$.ajax({ url: "/foo", type: "POST", data: input_string, success: recvFoo });
}
XMLHttpRequest object's open() method allows you to specify the HTTP method while the send() method allows to specify the message body, e.g.
var xhr = ... // obtain XMLHttpRequest object
xhr.open('POST', '/foo'); // HTTP method and requested URL.
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
recvFoo(xhr.responseText); // Will pass 'baz' to recvFoo().
}
};
xhr.send('bar'); // Message body with your function's argument.
No need to fallback to classic JavaScript
$.ajax({
url:"URL of foo...",
type: "POST",
data: "what ever",
success: recvFoo
});
Or the post option:
$.post('The url of foo', {input_string : 'bar'}, recvFoo);
jQuery post will do the job:
$.post('foo.html', {'varname' : 'bar'}, function(data) {
recvFoo(data);
});
Very well laid out question, thanks.