I need to call an external API to get some data from a SuiteScript file and I'm getting an issue. The GET call needs to go with credentials (basically, it has to go with the cookies in the Request Header).
If I make the API call from the chrome console setting withCredentials = true, but when I make that API call with NetSuite N/https module -through https.get()- the cookies don't go on the request header.
So in summary, I'm looking for a way to set withCredentials = true on the http.get() call or to be able to somehow get the cookies from my SuiteScript so that I can manually set it in the header option of the call.
Thanks in advance for your time!
Within the get, pass the headers option and populate your header values. I believe these are KVP.
If your external app is expecting information about the logged in user then what you probably want to do is an XHR request (jQuery's $.getJSON would be your best bet). If you need to pass information to a server side script then you'd call your Suitelet with the returned data.
A post example would be as follows. Note the withCredentials :
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: url,
dataType: "json",
data: jsonData,
xhrFields: {
withCredentials: true
},
success: function(response){
console.log(response);
},
error: function(response){
console.log('error: ' + JSON.stringify(response));
}
});
Related
I want to send multiple files to Github repository via nodejs. Tried several approaches and end up using node-rest-client module. Tried below code send a sample file to repository called 'metadata'. But after post I am getting error message "Request forbidden by administrative rules. Please make sure your request has a User-Agent header"...please let me know if anyone faced this error before and get rid of it.
convertval = "somedata";
var dataObj = {
"message": "my commit message",
"committer": {
"name": "Scott Chacon",
"email": "ravindra.devagiri#gmail.com"
},
"content": "bXkgbmV3IGZpbGUgY29udGVudHM="
}
debugger;
var Client = require('node-rest-client').Client;
var client = new Client()
var args = {
data: dataObj,
headers: { 'Content-Type': 'application/json' },
};
client.post("https://api.github.com/repos/metadata/contents", args, function (data, response) {
console.log("file send: True : " + data);
});
According to the REST API:
All API requests MUST include a valid User-Agent header. Requests with
no User-Agent header will be rejected.
First of all, you need to define 'User-Agent' with value 'request' in your request header. Refer to this link.
Second, endpoint you are trying to call might require authentication. Generate a personal token from here, add that token in your request header, 'Authorization': 'token '.
If you're using Git extensively in your code, I suggest you to use this - Nodegit.
Edit:
I don't think sending multiple files in a single request is possible in 'Contents' endpoints group (link).
You can checkout Git Data API (as discussed here).
Right now this is how I am doing it.
I have an ajax call on client side which hits a route like "/gettoken"
When the above is called, its passed to my node server where I do a router.get("/gettoken", function etc etc), and within this, I do a router.post("url of external server i want to get token from", function etc etc), then res.json(response.token).
Then on client side in the call i made in 1) I get the response inside the .then(function(data)), i use that token received on client side to send another ajax call (yes an ajax call within an ajax call). The 2nd ajax call sends the toke to another route like "/sendtokenforapicall"
on node server side again, I use router.get("/sendtokenforapicall") and within this I do a router.post("url for external api route") and pass the token along with it to get the relevant response back
Is my flow correct? what is the correct way or better way of doing this?
In order to make HTTP requests from your server to an external url, you need to use something other than your router. Your router is for listening to incoming requests.
To actually execute HTTP requests from your server to an URL, try using fetch like this
var url = 'https://example.com/profile';
var data = {username: 'example'};
fetch(url, {
method: 'POST', // or 'PUT'
body: JSON.stringify(data), // data can be `string` or {object}!
headers:{
'Content-Type': 'application/json'
}
}).then(res => res.json())
.then(response => console.log('Success:', JSON.stringify(response)))
.catch(error => console.error('Error:', error));
I've been playing around with some web scraping but I've run into an issue I can't figure out; Using a nodejs server (on my local computer) I cannot get passed a permission error barring me from accessing the data. What is confusing to me most is that using the chrome extension "Postman" I don't run into the permission errors, but using the code generated by postman, I do (as well as fiddling with variations of my own scratch code).
Do I have to be using a live server? Do I need to include some extra items in the headers that aren't being put there by Postman? Is there some layer of security around the API that for some reason Postman has access do that a local machine doesnt?
Any light that can be shed would be of use. Note that there is no public documentation of the SmithsFoodAndDrug API (that I can find), so there aren't necessarily APIKeys that are going to be used. But the fact that Postman can access the information makes me think I should be able to on a node server without any special authentication set up.
In Summary:
I'm looking at SmithsFoodAndDrug product information, and found the API where they are grabbing information from.
I figured out the headers needed in order to get local price information on products (on top of the json body format for the POST request)
Using postman I can generate the POST request and retrieve the desired API results
Using nodejs (and the code generated by postman to replicate the request) with both 'request' module and standard 'http' module request module I receive permission errors from the server.
Details: (assume gathering data on honeycrisp apples (0000000003283) with division-id of 706 and store-id of 00144)
http://www.smithsfoodanddrug.com/products/api/products/details
Headers are 'division-id' and 'store-id'. Body is in format of {"upcs":["XXX"],"filterBadProducts":false} where XXX is the specific product code.
Here are the Request Headers in postman. Here are the Request Body settings in postman. The following is a portion of the json response (which is what I want).
{"products": [
{
"brandName": null,
"clickListItem": true,
"countryOfOrigin": "Check store for country of origin details",
"customerFacingSize": "price $2.49/lb",
...
"calculatedPromoPrice": "2.49",
"calculatedRegularPrice": "2.99",
"calculatedReferencePrice": null,
"displayTemplate": "YellowTag",
"division": "706",
"minimumAdvertisedPrice": null,
"orderBy": "Unit",
"regularNFor": "1",
"referenceNFor": "1",
"referencePrice": null,
"store": "00144",
"endDate": "2018-09-19T00:00:00",
"priceNormal": "2.55",
"priceSale": "2.12",
"promoDescription": "About $2.12 for each",
"promoType": null,
...
"upc": "0000000003283",
...
}
],
"coupons": {},
"departments": [],
"priceHasError": false,
"totalCount": 1 }
When using the code given by postman to replicate the request, I get the error saying 'You don't have permission to access "http://www.smithsfoodanddrug.com/products/api/products/details" on this server.
Reference #18.1f3de93f.1536955806.1989a2b1.' .
// Code given by postman
var request = require("request");
var options = { method: 'POST',
url: 'http://www.smithsfoodanddrug.com/products/api/products/details',
headers:
{ 'postman-token': 'ad9638c1-1ea5-1afc-925e-fe753b342f91',
'cache-control': 'no-cache',
'store-id': '00144',
'division-id': '706',
'content-type': 'application/json' },
body: { upcs: [ '0000000003283' ], filterBadProducts: false },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
change headers
headers:
{
'store-id': '00144',
'division-id': '706'
//'content-type': 'application/json'
}
I am using the infamous request library to send requests.
One of those requests requires me to send the header multipart/mixed; boundary={myboundary}.
Request is using the form-data library for such requests but it does not set the Content-Type header properly. Therefore I would need to set it like this:
let req = request.post({url: "https://..."}, formData: formData)
req.setHeader('Content-Type', `multipart/mixed; boundary=${req.form().getBoundary()}`)
Sadly I can't add/alter any headers after firing the request. Therefore I want to know whether there is a way to intercept the sending so I can change the header?
You will need to use the multipart option instead of formData to use other, arbitrary multipart/* content types. Each object in the multipart array contains the headers to send in that part. The one exception is the body property which is used as the actual body of that part.
request.post({
url: 'https://...',
multipart: [
{ 'X-Foo-Header': 'bar', body: 'baz' },
// ...
],
headers: { 'Content-Type': 'multipart/mixed' }
});
The boundary should be automatically appended for an existing, explicit Content-Type header. This request test explicitly tests for this behavior.
I am trying with passport-facebook ajax
client
$('#fb').click(function(){
$.ajax({
url:'/auth/facebook',
type: 'post',
success:function(data){
if(data.result == true){
...
}else{
...
}
},
error:function(request,status,error){
console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
})
});
error message
XMLHttpRequest cannot load https://www.facebook.com/dialog/oauth?~~~
...
Response for preflight is invalid (redirect)
i don't know this error..
help me please
Facebook does not allow scripts to load the login dialog, i guess to prevent phishing. You need to do the GET request via the browser URL by an anchor tag. Or you can get around it in your AJAX by doing:
window.location.replace('http://yourdomain/auth/facebook')