Safebrowsing API returns 'Invalid JSON payload received' - javascript

I'm using Safe browsing API to check some URLs from my database, but the request gives me this result:
data {
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"threatInfo[threatTypes][0]\": Cannot bind query parameter. Field 'threatInfo[threatTypes][0]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"threatInfo[threatTypes][1]\": Cannot bind query parameter. Field 'threatInfo[threatTypes][1]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"threatInfo[platformTypes][0]\": Cannot bind query parameter. Field 'threatInfo[platformTypes][0]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"threatInfo[threatEntryTypes][0]\": Cannot bind query parameter. Field 'threatInfo[threatEntryTypes][0]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"threatInfo[threatEntries][0][url]\": Cannot bind query parameter. Field 'threatInfo[threatEntries][0][url]' could not be found in request message."
}
}
I'm trying the following code:
const request = require('request');
const body = {
threatInfo: {
threatTypes: ["SOCIAL_ENGINEERING", "MALWARE"],
platformTypes: ["ANY_PLATFORM"],
threatEntryTypes: ["URL"],
threatEntries: [{url: "http://www.urltocheck2.org/"}]
}
}
const options = {
headers: {
"Content-Type": "application/json"
},
method: "POST",
url: "https://safebrowsing.googleapis.com/v4/threatMatches:find?key=${API_KEY}",
form: body
}
console.log(options);
request(options,
function(err, res, data) {
console.log('data', data)
if (!err && res.statusCode == 200) {
console.log(data);
}
}
)
I expected the output of the request be {} with a 200 status code on this sample.

If you look in the request() doc for the form property, you will see this:
form - when passed an object or a querystring, this sets body to a querystring representation of value, and adds Content-type: application/x-www-form-urlencoded header. When passed no options, a FormData instance is returned (and is piped to request). See "Forms" section above.
When you look at the Google safe browsing API, you will see this:
POST https://safebrowsing.googleapis.com/v4/threatMatches:find?key=API_KEY HTTP/1.1
Content-Type: application/json
You are sending Content-type: application/x-www-form-urlencoded, but the API wants Content-Type: application/json. You need to send JSON, not form encoded data.
You can probably just change the form property to the json property by changing from this:
const options = {
headers: {
"Content-Type": "application/json"
},
method: "POST",
url: "https://safebrowsing.googleapis.com/v4/threatMatches:find?key=${API_KEY}",
form: body
}
to this:
const options = {
method: "POST",
url: "https://safebrowsing.googleapis.com/v4/threatMatches:find?key=${API_KEY}",
json: body // <=== change here
}
The content-type is automatically set either way to match the format of the generated body so you don't need to set it.

Related

No response from API

I have created an API call in excel to get data from a Wix database.
The call:
Dim http As Object, JSON As Object
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", "https://username.wixsite.com/mysite/_functions/Functionname", False
http.setRequestHeader "Authorization", "myauthkey"
http.Send
MsgBox (http.responseText)
The javascript http backend file on Wix:
import { ok, notFound, serverError } from 'wix-http-functions';
import wixData from 'wixdata';
export function get_Wixdata() {
let options = {
"headers": {
"content-type": "application/json"
}
};
return wixData.query("wix data collection name")
.find()
.then(results => {
if (results.items.length > 0) {
options.body ={
"items": results.items
}
return ok(options);
}
})
}
I tested the call (without authorisation) on JSON place holder and it worked fine.
Just trying to debug what's happening as I am getting "" as a response.
Even if I enter the wrong API key I still get "", even a wrong url it's still a "" response.
I take it I am clearly way off the mark with what I am trying to do..
Did you tried put both headers in your request, like the following:
let headers = new Headers({
'Content-Type': 'application/json',
'Authorization': '....'
});
The issue was with the VBA call, the header was not needed.
Dim https As Object, JSON As Object
Set https = CreateObject("MSXML2.XMLHTTP")
With CreateObject("Microsoft.XMLHTTP")
.Open "GET", "end point url", False
.send
response = .responseText
End With

When sending POST request to backend API via fetch(), the body has only key and no value

When I'm sending a POST request to my backend express server, the req.body contains only the key part where the entire body is the key and the value part is empty
This is the frontend fetch request
let data = {
videoUrl: "dummy text"
}
fetch("/api/getinfo", {
method:"POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
},
body: JSON.stringify(data)
})
This is how I handle it in backend (NOTE: I'm using body-parser)
app.post("/api/getinfo", (req,res) => {
console.log(req.body);
}
I expect the output to be
'{ "videoUrl":"dummy text" }'
But what I get is
{ '{"videoUrl":"dummy text"}': '' }
The entire requests body is the key, and the value is empty.
What am I doing wrong?
You are using the wrong Content-Type to send json
Try
"Content-Type": "application/json;charset=UTF-8"
I noticed an issue in your header;
fetch("/api/getinfo", {
method:"POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" //this very line
},
I guess what you meant is
fetch("/api/getinfo", {
method:"POST",
headers: {
'Content-type': 'application/json; charset=utf-8'
},
Note: Your header denotes what the content is encoded in. It is not necessarily possible to deduce the type of the content from the content itself, i.e. you can't necessarily just look at the content and know what to do with it. So you need to be sure of what you're writing in your header else you will end up with an error.
I will suggest you get to read more about What does “Content-type: application/json; charset=utf-8” really mean?
The problem is that you are stringifying the data:
body: JSON.stringify(data)
should be
body: data
That should fix it

request.post in Node throws { code: undefined, reason: 'Argument error, options.body.' }

I am getting the following error when trying to perform a request.post. It's confusing because it seems to be first referring to the body of my options but then complains about the first argument should be a string or buffer.
{ code: undefined, reason: 'Argument error, options.body.' }
DOH!
_http_outgoing.js:454
throw new TypeError('first argument must be a string or Buffer');
^
TypeError: first argument must be a string or Buffer
I tried changing the url value to a string but that doesn't fix it.
Here is what my code looks like. As you can see I've logged out the reqOptions and have verified that the url is definitely being passed to the request.postso I am not sure what the problem is. Cheers for any help!
var reqOptions = {
url: options.host,
body: formData,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
console.log('CHECK OPTIONS :: ', reqOptions);
request.post(reqOptions, function (err, resp) {...}
If formData is an object, you'll probably want to use request's form: option instead of body:. That will both stringify the object and set the Content-Type header.
var reqOptions = {
url: options.host,
form: formData
};
console.log('CHECK OPTIONS :: ', reqOptions);
request.post(reqOptions, function (err, resp) {...});
The body: option expects a value that is either a string, Buffer, or ReadStream. Without using form:, you'll have to stringify the object yourself.
var qs = require('querystring');
var reqOptions = {
url: options.host,
form: qs.stringify(formData),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
add json : true
request({
url : url,
method :"POST",
headers : {
"content-type": "application/json",
},
body: body,
json: true
},

malformed JSON string Error while passing JSON from AngularJS

I am trying to pass JSON string in ajax request. This is my code.
NewOrder = JSON.stringify (NewOrder);
alert (NewOrder);
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: "mydata="+ NewOrder
};
$http(req)
.success(function (data, status, headers, config) {
alert ('success');
})
.error(function (data, status, headers, config) {
alert (status);
alert (data);
alert ('Error')
});
alert (NewOrder) gives -
{"ItemList":[{"ItemName":"Quality Plus Pure Besan 500 GM","Quantity":1,"MRP":"28.00","SellPrice":"25.00"}],"CustomerID":1,"DeliverySlot":2,"PaymentMode":1}
Which seems to be a valid JSON string.
But in script side I am getting following error. in this line
my $decdata = decode_json($cgi->param('mydata'));
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)")
Can please someone help me why i am getting this error?
$cgi->param('myData') returns the query param string 'mydata', which in your case is not sent.
You're posting the json data in the request body of your http post payload, and not as a query/form param. In that case, you'd need some other function to read the contents of the request body in your server-side script.
which happens to be:
my $data = $query->param('POSTDATA');
as described in here: http://search.cpan.org/~lds/CGI.pm-3.43/CGI.pm#HANDLING_NON-URLENCODED_ARGUMENTS
Also you should remove the "mydata=" from your json in the body you post, because http request payload bodies do not have parameter names (they're for query/form-params only).
Your end code should be like this:
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: NewOrder
};
and the servers side:
my $decdata = decode_json($query->param('POSTDATA'));
I think it may be related to this issue: AngularJs $http.post() does not send data
Usually I would post data like this:
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: {"mydata" : NewOrder}
};
However I am assuming that you are expecting the data as request params from this:
my $decdata = decode_json($cgi->param('mydata'));
If that is the case then the linked SO question is what you are looking for.
Angular $http.post accepts two params as url and payload
var url = '/cgi-bin/PlaceOrder.pl';
var payLoad = {'myData' :JSON.stringify(NewOrder)};
$http.post(url, payLoad)
.success(function(data) {
console.log(success);
})
At the server side, while fetching the required json string from the request param and then desearlize the json as following:
$result = $cgi->param('myData');
my $decdata = decode_json($result);

Facebook Marketing API | node js | "message":"Unsupported post request.","type":"GraphMethodException","code":100

I am trying to use the Facebook Marketing API to create a new ad campaign in Node.js.
I have successfully gotten an access token from this url:
var fbApi = {
'method': 'GET',
'url' : 'https://graph.facebook.com/oauth/access_token?client_id=MYCLIENTID&client_secret=MYSECRET&grant_type=client_credentials'
}
I then make this POST request (using the 'request' module).
I am posting values for 'name' and 'campaign_group_status' which I understand are required values.
I am posting to the endpoint
https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/adcampaign_groups
and I'm passing the access token via the URL as per this from the docs:
http://graph.facebook.com/endpoint?key=value&access_token=app_id|app_secret
.
Full code (sensitive info replaced by dummy data):
var request = require('request');
var fbOptions = {
'name' : 'test2',
'campaign_group_status' : 'PAUSED'
}
var fbOptionsString = JSON.stringify(fbOptions);
var fbPost = {
'uri' : ' https://graph.facebook.com/v2.3/act_5374356645419299/adcampaign_groups?access_token=56345345453773242|iert_arfwYfwfwxD-pLxHcpASFTNm',
'method': 'POST',
'headers': {
'Content-Type' : 'application/json',
},
'body' : fbOptionsString
}
request(fbPost, function(error, response, body){
console.log('request says ----', body);
})
.
Error response that I'm seeing:
request2 says ---- {"error":{"message":"Unsupported post request.","type":"GraphMethodException","code":100}}
.
Before I was getting an error about permission, and another saying the 'name' value was required. Those have been solved. So I believe I have the right access and Facebook is getting the body content of the request.
Help would be greatly appreciated!
If you look at the documentation examples, they use the -F option in curl.
-F, --form <name=content>
(HTTP) This lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388. This
enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an # sign. To just get the content part from a file, prefix the file name with the symbol <.
The difference between # and < is then that # makes a file get attached in the post as a file upload, while the < makes a text field and just get the contents for that text field from a file.
So you have to send the data from a post multi-part.
See here to learn how to do so with node-request.
var request = require('request');
var fbOptions = {
'name' : 'test2',
'campaign_group_status' : 'PAUSED'
}
// var fbOptionsString = JSON.stringify(fbOptions);
var fbPost = {
'uri' : ' https://graph.facebook.com/v2.3/act_5374356645419299/adcampaign_groups?access_token=56345345453773242|iert_arfwYfwfwxD-pLxHcpASFTNm',
'method': 'POST',
'headers': {
'Content-Type' : 'application/json',
},
'formData' : fbOptions
}
request(fbPost, function(error, response, body){
console.log('request says ----', body);
})
This code sample is not tested.

Categories

Resources