HTTPS request with node.js? - javascript

I need to trigger a request in my node.js app. My app has a route and when it runs I am trying to hit a url that is built dynamically. So all I need is to trigger a RESt API call to somethinglike:
"https://www.domainname.com/sometext/"+ var1 +"/someothertext"
So I tried this:
var options = {
host: 'www.domainname.com',
port: 80,
path: '/1.0/'+var1,
method: 'GET'
};
// trigger request
request(options, function(err,response,body) {
.......
});
When I run this I get this error:
options.uri is a required argument
So, my goal here is to trigger the request that hits a dynamically built url. If I had a static url I could plug in the request, it would work fine.
Infact I tried to do this:
request("https://www.domainname.com/1.0/456", function(err,response,body) {
.......
});
and this works fine.
BUT I am trying to build the url (path) dynamically with var1 and that doesn't work.
Any suggestion on how to do this?

You need a URL or an URI in the options that you pass as the first arguments to the request function
And the reason that request("https://www.domainname.com/1.0/456",function(err,response,body) {
does not fail is because you are providing the url as the first argument
So change your options object to
var options = {
url: 'https://www.domainname.com/sometext/'+ var1,
port: 80,
method: 'GET'
};
You can try trimming the value in var1 like
var1 = var1.replace(/^\s*|\s*$/g, '');
That should remove the space.

Because the options argument that is taken by request isn't being given the correct formatted object.
The error you are receiving is because you need to send a url or uri as an option. This can be clarified here:
https://github.com/request/request
The following should do what you want:
So I tried this:
var options = {
url: "https://www.domainname.com/sometext/"+ var1 +"/someothertext"
method: 'GET'
};
// trigger request
request(options, function(err,response,body) {
console.log(response.statusCode);
});

Related

HTTPS POST request is not passing any data

I am trying to replay a request to another instance of my API, so I am making a POST request as shown below. This works fine except for the fact that the data (JSON.stringify(req.body)) is not being passed. req.body on the other instance returns a blank map {} even though I have confirmed that JSON.stringify(req.body) returns what I expect. Is there something wrong with how I am passing the data with the POST request? Thanks in advance for any help.
var betaReq = https.request({
hostname: 'some-product-beta.cloudfunctions.net',
path: '/intercomEventsReplayed',
method: 'POST',
headers: {
'x-hub-signature': req.headers['x-hub-signature']
}
});
betaReq.write(JSON.stringify(req.body));
betaReq.end();

How do I sent additional data to javascript's fetch() function

I want to use fetch() to query an API endpoint which powers my search page. It returns a list of search results in JSON format.
I also want to pass to the API the current query submitted by the user. The old implementation used jquery and getJSON. Looking at the docs for getJSON, it says that I can pass in a data variable:
data
Type: PlainObject or String
A plain object or string that is sent to the server with the request.
Looking at the docs for fetch, I'm not sure how to pass in data as part of my request. So my question is, how do I pass in a string that will be sent to the server along with my request?
EDIT: I think I can append the query to the request URL, like "/search/?q=Something" and send that. Does anyone have a better way?
If you look at the Body section of the documentation on fetch, it lists several types of values you can use to specify the data sent in your request.
Example using FormData:
var fd = new FormData();
fd.append('q', 'Something');
fetch('/search', {
method : "POST",
body : fd
})
.then(...)
Note that you can't use the body option on GET or HEAD requests (which it seems you may be doing in your case). In that situation, you can build up the parameters using URLSearchParams:
var params = new URLSearchParams();
params.append('q', 'Something');
fetch('/search/?' + params.toString(), {
method: 'GET'
})
.then(...);
You can pass as below
fetch('/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Hubot',
login: 'hubot',
})
})

Change query string parametesr of JavaScript requests

Is there a way to change the query string of JavaScript-induced requests? I want to add "&myParam=myValue" to any request sent by my HTML/JS application.
I don't think there's anything built in that lets you do that.
In my apps, I always have a central function XHR goes through so I have a single point to do things like this. If you don't have that or need to intercept calls from 3rd party libs:
You could wrap XMLHttpRequest.open to handle the XHR ones:
var originalOpen = XMLHttpRequest.open;
XMLHttpRequest.open = function() {
var args = Array.prototype.slice.call(arguments);
args[0] += (args[0].indexOf("?") == -1 ? "?" : "&") + "myParam=" + encodeURIComponent("myValue");
return originalOpen.apply(this, args);
};
...and then similar for fetch. But it seems brittle.
Alternately, you might look at using a cookie for the parameter, as the browser will add the cookie to the requests. (That assumes the requests are going to an origina you can add cookies for in your code.)
You could use partial application to lock in defaults when you declare your fetch function and essentially decorate the standard call that will merge your defaults and the passed params.
const fetchFactory = defaults => (url, data) => {
// make a copy of the defaults
const params = Object.assign({}, defaults)
// assign the passed in data with the defaults
params.body = JSON.stringify(Object.assign(params.body, data))
// call fetch with the params
return fetch(url, params)
}
// create a default for POST using the factory
const postFetch = fetchFactory({
method: 'post',
headers: {
'x-requested-with': 'fetch',
'Authorization': 'basic:' + btoa('a secret')
},
body: {
myParam: 'value'
}
})
// now you can call your function
postFetch('http://somewhere.com', {
one: 1,
two: 2
})
.then(respone => response.json())
It seems to me that you are asking how to set/edit URL parameters in http requests. Something quite similar has been asked here: here
If you are using XMLHttpRequest then the accepted answer in the link should work perfectly. The two key things the note are
the url parameters are simply a javascript object that you convert
into a JSON string. This happens through JSON.stringify({ myParam:
'hi'});
the question/answer linked are making post requests but you
may not want to make that request as well, I suggest doing some
research about which HTTP request method you want -
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Getting s.Type.ToUpperCase() is not a function when calling WCF service with $ajax

I'm using WCF and I am getting this error.
If I use jQuery1.14.1 I get
Type error: s.type.ToUpperCase is not a function
type = s.type.ToUpperCase();
If I use jQuery 1.12.1 locally the service gets called corrctly. However, if I try it on the server, 1.14.1 get the error above, but 1.12 i get this one:
Type error: l.type.ToUpperCase() is not a function
..+&&n.event.trigger("ajaxStart"),l.type=l.type.ToUpperCase(), l,hasContent=!Kb.tes....
Relevant code:
var Type = "POST";
var DataType = "jsonp";
var ProcessData = true;
var ContentType = "application/json; charset=utf-8";
var params = {
user: $("#userid_hidden").val().toString(),
permission: $("#permission_id_" + i).val().toString(),
enabled: true,
note: $("#permission_note_" + i).val(),
write: $("#permission_write_" + i).is(":checked")
}
SetPermission(params);
function SetPermission(params) {
//alert('setting permission');
if (params.enabled)
CallService('wsEnablePermissionJSON', params);
else
CallService('wsDisablePermissionJSON', params);
}
function CallService(wsName, params) { //Generic function to call WCF Service
alert('calling service');
$.ajax({
type: Type, //GET or POST or PUT or DELETE verb
url: Url + wsName, // Location of the service
data: JSON.stringify(params),
/*data: JSON.stringify(params), //Data sent to server*/
contentType: ContentType, // content type sent to server
dataType: DataType, //Expected data format from server
processdata: ProcessData, //True or False
success: function(msg) { //On Successful service call
ServiceSucceeded(msg, wsName);
},
error: ServiceFailed // When Service call fails
});
alert('service called');
}
I can't see the rest of the error because the page is then reloaded, I got those by taking a screenshot.
I don't know how to go about this, I've tried jQuery 2 and I get the first error. I've used the same ajax call with another wcf service and it's currently working fine (the only difference is that the working one uses jQuery 1.12, and that solved it locally, in the server the new one fails.)
Both pages are in the same server.
I've been trying to figure this out for most of the day, but I haven't found anything, at first I thought that using 1.12 would solve it.
I googled the error but all the results were for different cases, I didn't see anything for the $ajax call.
This was happening pecause the name of the variable Type
var Type = "POST";
I didn't think to change it before, because as I've said before I have another web app very similar, and with exactly the same ajax call working fine, and that code I got from an example somewhere.
Changing it to
var Requestype = "POST";
took care of the error
I ran into the same error, but for a different reason. I was accidentally passing the value true in the type property, instead of a POST.
If it contains any value other than the accepted verbs. Remember that it defaults to GET, if none provided.
Hope this helps somebody.

Angular $http attach data as object

I'm trying to get list of tracks from soundcloud API with angularjs.
The parameters i'm trying to send are:
1) client_id (string)
2) duration (object with two properties).
Here's the code:
var CLIENT_ID = 'a81f01ef5d0036415431e8be76c8db0e';
var TRACKS_URL = 'https://api.soundcloud.com/tracks.json';
var app = angular.module('soundcloud', []);
app.controller('tracksController', function ($scope, $http) {
$http({
url: 'https://api.soundcloud.com/tracks.json',
method: 'GET',
data: {
client_id: CLIENT_ID,
duration: { // in milliseconds
from: 300000,
to: 400000
}
}
})
.success(function (data) {
$scope.trackList = data;
})
.error(function () { alert('error'); });
});
These parameters aren't recognized at all when I check the request in the broweser's debugger.
I tried to use 'params' instead of 'data', but this way it turns the 'duration' object to json --> then I get status 500 in response.
When I only send the client_id in params, it works fine because there's no object, only string.
jQuery's ajax method works fine: https://jsfiddle.net/oacwz1up/3/
What should I do ? How can I send the parameters normally ?
Help please! Thanks!
This happens because Angular serializes the request parameters differently than JQuery.
Angular 1.4 will address this problem introducing a paramSerializer property on the $http config object (and on $httpProvider.defaults). This can be used for arbitrarily serializing the requests parameters (for all or a particular request).
Note, that the feature is available only since v1.4.0-rc.0.
Besides the default serializer (which converts objects to JSON strings), there is an additional built-in serializer that emulates JQuery's param(): $httpParamSerializerJQLike.
You can use it like this:
$http.get(<API_URL>, {
params: {...},
paramSerializer: '$httpParamSerializerJQLike'
});
See, also, this short demo.
If you are using an older version of Angular, you could do one of the following:
Construct the whole URL (including the query string) yourself (possibly using an $http request interceptor to automatically apply this to all requests).
Keep the params in a flat format that will result in Angular's serializing them as expected:
var REQ_PARAMS = {
client_id: 'a81f01ef5d0036415431e8be76c8db0e',
'duration[from]': 200000,
'duration[to]': 205000
};
If you look at $http documentation, on request it applies a default transformation which is $http.defaults.transformRequest and as described will do the following (as you saw) :
If the data property of the request configuration object contains an object, serialize it into JSON format.
What you need to do is override this function by specifying your own transformRequest object.
function appendTransform(defaults, transform) {
// We can't guarantee that the default transformation is an array
defaults = angular.isArray(defaults) ? defaults : [defaults];
// Append the new transformation to the defaults
return defaults.concat(transform);
}
$http({
url: '...',
method: 'GET',
transformResponse: appendTransform($http.defaults.transformResponse, function(value) {
return doTransform(value);
})
});
You need to find a way to get the same syntax as jQuery provide which is :
https://api.soundcloud.com/tracks.json?client_id=a81f01ef5d0036415431e8be76c8db0e&duration[from]=200000&duration[to]=205000
Use a condition is is an object and generate manually your String. Should not be difficult.
that's a strange API - I don't know why they don't do something like "duration_from" rather than requiring duration[from] - as suggested you could certainly transform the request, but if this is just a one off you could also try simply hard-coding it using url escaped values for [ and ]:
var dataToSend = {
client_id: 'a81f01ef5d0036415431e8be76c8db0e',
'duration%5Bfrom%5D': 200000,
'duration%5Bto%5D': 205000
};
$http.get('http://api.soundcloud.com/tracks.json', {params:dataToSend});
The params property is way to transform query in restful way. Just transform data in dataToSend object, and it will work.
This is a URL that should be created:
https://api.soundcloud.com/tracks.json?client_id=a81f01ef5d0036415431e8be76c8db0e&duration%5Bfrom%5D=200000&duration%5Bto%5D=205000

Categories

Resources