I'm trying to send a POST request to an endpoint which accepts JSON and it doesn't work. Do I have to send any specific parameter in order to let the network know it is encoded as JSON?
Here is the simple request I've so far:
var request = require('request')
var cookie = '**Here the cookie copied from the Network tab from the Chrome Dev Tools Bar**'
var UA = '**Here the UA copied from the Network tab from the Chrome Dev Tools Bar**'
var JSONformData = {"jsonrpc":"2.0","method":"LMT_split_into_sentences","params":{"texts":["Text"],"lang":{"lang_user_selected":"auto","user_preferred_langs":["EN","ES"]}},"id":8}
var URL = 'https://www.deepl.com/jsonrpc'
request.cookie(cookie)
request.post({
url: URL,
headers: {
'User-Agent': UA
},
form: JSONformData
}, function(error, response, body) {
console.log(response)
}
)
If you are sending JSON data then you don't need to specify the form, instead specify the json for data in the options object:
request.post({
url: URL,
headers: {
'User-Agent': UA
},
json: JSONformData
}, function(error, response, body) {
console.log(response)
})
Related
Here is a sample POST request which I run inside the Console window of Chrome.
fetch("https://demo.wpjobboard.net/wp-login.php", {
"headers": {
"Host": "demo.wpjobboard.net:443",
"Content-Length": "19",
"Cookie": "wpjb_transient_id=1607759726-1847; wordpress_test_cookie=WP+Cookie+check",
"Content-Type": "application/x-www-form-urlencoded"
},
"body": "log=7887&pwd=789789",
"method": "POST",
}).then(console.log);
I need to navigate and see HTML rendered results inside the chrome, not just seeing some complex results inside the console. How to achieve this?
Fetch returns promise and first what you get is streaming data from your server. You need to convert it to text or JSON after that you can use it like a normal variable.
I have moved your URL and options in separate variables in order to focus code on fetch request implementation.
const url = `https://demo.wpjobboard.net/wp-login.php`
const opts = {
headers: {
'Cookie': `wpjb_transient_id=1607759726-1847; wordpress_test_cookie=WP+Cookie+check`,
'Content-Type': `application/x-www-form-urlencoded`
},
body: `log=7887&pwd=789789`,
method: `POST`,
}
fetch(url, opts)
.then(res => res.text()) // if you get json as response use: res.json()
.then(html => {
const win = window.open(``, `_blank`)
win.document.body.innerHTML = html
win.focus()
})
API request to quandl for fetching stock data returning HTML response instead of JSON. Its correctly returning JSON result in postman.
var url ='https://www.quandl.com/api/v3/datasets/BSE/BOM'+532540+'?start_date='+startDate+'&end_date='+endDate+'&collapse=weekly&api_key=myapikey'
console.log(url)
var options =
{
'muteHttpExceptions': true,
"contentType" : "application/json",
};
var response = UrlFetchApp.fetch(url, options);
console.log(response)
did anyone have a workaround?
Issue:
Xml response instead of JSON response from quandl api
Solution:
Explicitly mention the format in the url as mentioned in the documentation
GET https://www.quandl.com/api/v3/datasets/{database_code}/{dataset_code}/data.{return_format}
var url ='https://www.quandl.com/api/v3/datasets/BSE/BOM'+532540+'.json?start_date='+startDate+'&end_date='+endDate+'&collapse=weekly&api_key=myapikey'
AND/OR
Try mentioning that you only accept json response in the request using Accept header.
var options =
{
'muteHttpExceptions': true,
"contentType" : "application/json",
"headers":{"Accept":"application/json"}
};
I created an API in laravel and tested in postman and it is working perfect. But when I try it from angular it works fine for returning a string text but not for JSON response
I searched it on internet and found setting content-type:application/json and tried with different ways for setting content type in header but issue still persist
var obj = JSON.parse('{"email":"ab#gm.com","password":"12345678"}');
//1st type of header
var headers_object = new HttpHeaders().set('Content-Type',
'application/json');
const httpOptions = {
headers: headers_object
};
//2nd type of header
var HTTPOptions = {
headers: new HttpHeaders({
'Accept':'application/json',
'Content-Type': 'application/json'
}),
'responseType': 'application/json' as 'json'
}
return this.http.post<any>(`http://127.0.0.1:8000/api/auth/login`, obj,HTTPOptions ).subscribe(resp => {
console.log(resp);
});
Postman Output
browser network request/response
return this.http.post(http://127.0.0.1:8000/api/auth/login, obj,HTTPOptions ).map((resp: Response) => resp.json())
hopefully this will work
Basically, you are sending "string JSON" instead JSON Object, send Javascript Object directly instead of string will solve your issue,
Use the below-mentioned way to post JSON data to the server,
var httpOptions = {
headers: new HttpHeaders({
'Accept':'application/json',
'Content-Type': 'application/json'
})
};
var dataToPost = {"email":"ab#gm.com","password":"12345678"};
this.http.post('http://127.0.0.1:8000/api/auth/login', dataToPost, httpOptions)
.subscribe(resp => {
console.log(resp);
});
It was due to CORB.
Cross-Origin Read Blocking (CORB) is an algorithm that can identify
and block dubious cross-origin resource loads in web browsers before
they reach the web page. CORB reduces the risk of leaking sensitive
data by keeping it further from cross-origin web pages.
https://www.chromestatus.com/feature/5629709824032768
Solution run chrome in disabled web security mode.
This worked for me https://stackoverflow.com/a/42086521/6687186
Win+R and paste
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
I need to make a GET request to an API from my Flutter app which requires request body as JSON (raw).
I tested the API with JSON request body in Postman and it seems to be working fine.
Now on my Flutter application I am trying to do the same thing:
_fetchDoctorAvailability() async {
var params = {
"doctor_id": "DOC000506",
"date_range": "25/03/2019-25/03/2019" ,
"clinic_id":"LAD000404"
};
Uri uri = Uri.parse("http://theapiiamcalling:8000");
uri.replace(queryParameters: params);
var response = await http.get(uri, headers: {
"Authorization": Constants.APPOINTMENT_TEST_AUTHORIZATION_KEY,
HttpHeaders.contentTypeHeader: "application/json",
"callMethod" : "DOCTOR_AVAILABILITY"
});
print('---- status code: ${response.statusCode}');
var jsonData = json.decode(response.body);
print('---- slot: ${jsonData}');
}
However the API gives me an error saying
{message: Missing input json., status: false}
How do I send a raw (or rather JSON) request body for Http GET request in Flutter?
GET
GET requests are not intended for sending data to the server (but see this). That's why the http.dart get method doesn't have a body parameter. However, when you want to specify what you are getting from the server, sometimes you need to include query parameters, which is a form of data. The query parameters are key-value pairs, so you can include them as a map like this:
final queryParameters = {
'name': 'Bob',
'age': '87',
};
final uri = Uri.http('www.example.com', '/path', queryParameters);
final headers = {HttpHeaders.contentTypeHeader: 'application/json'};
final response = await http.get(uri, headers: headers);
POST
Unlike GET requests, POST requests are intended for sending data in the body. You can do it like this:
final body = {
'name': 'Bob',
'age': '87',
};
final jsonString = json.encode(body);
final uri = Uri.http('www.example.com', '/path');
final headers = {HttpHeaders.contentTypeHeader: 'application/json'};
final response = await http.post(uri, headers: headers, body: jsonString);
Note that the parameters were a Map on the Dart side. Then they were converted to a JSON string by the json.encode() function from the dart:convert library. That string is the POST body.
So if the server is asking you to pass it data in a GET request body, check again. While it is possible to design a server in this way, it isn't standard.
uri.replace... returns a new Uri, so you have to assign it into a new variable or use directly into the get function.
final newURI = uri.replace(queryParameters: params);
var response = await http.get(newURI, headers: {
"Authorization": Constants.APPOINTMENT_TEST_AUTHORIZATION_KEY,
HttpHeaders.contentTypeHeader: "application/json",
"callMethod" : "DOCTOR_AVAILABILITY"
});
using post:
var params = {
"doctor_id": "DOC000506",
"date_range": "25/03/2019-25/03/2019" ,
"clinic_id":"LAD000404"
};
var response = await http.post("http://theapiiamcalling:8000",
body: json.encode(params)
,headers: {
"Authorization": Constants.APPOINTMENT_TEST_AUTHORIZATION_KEY,
HttpHeaders.contentTypeHeader: "application/json",
"callMethod" : "DOCTOR_AVAILABILITY"
});
You can use Request class as following:
var request = http.Request(
'GET',
Uri.parse("http://theapiiamcalling:8000"),
)..headers.addAll({
"Authorization": Constants.APPOINTMENT_TEST_AUTHORIZATION_KEY,
HttpHeaders.contentTypeHeader: "application/json",
"callMethod": "DOCTOR_AVAILABILITY",
});
var params = {
"doctor_id": "DOC000506",
"date_range": "25/03/2019-25/03/2019",
"clinic_id": "LAD000404"
};
request.body = jsonEncode(params);
http.StreamedResponse response = await request.send();
print(response.statusCode);
print(await response.stream.bytesToString());
Also, note that Postman that can convert an API request into a code snippet in more than 15 languages. If you select Dart, you will find a similar code to above.
It may help someone those who used Getx for api integration . We can use request method for these kind of requirement.
Map<String, dynamic> requestBody = { 'id' : 1};
Response<Map<String, dynamic>> response =
await request(url, 'get', body: requestBody);
if you want to send complex/nested data through a GET request like the sample below, you can use a simple class i created on github
https://github.com/opatajoshua/SimplifiedUri
final params = {
'name': 'John',
'columns': ['firstName', 'lastName'],
'ageRange': {
'from': 12,
'to': 60,
},
'someInnerArray': [1,2,3,5]
};
final Uri uri = SimplifiedUri.uri('http://api.mysite.com/users', params);
final headers = {HttpHeaders.contentTypeHeader: 'application/json'};
final response = await http.get(uri, headers: headers);
output
http://api.mysite.com/users?name=John&columns%5B%5D=firstName&columns%5B%5D=lastName&ageRange%5Bfrom%5D=12&ageRange%5Bto%5D=60&someInnerArray%5B%5D=1&someInnerArray%5B%5D=2&someInnerArray%5B%5D=3&someInnerArray%5B%5D=5
I have published an app script publicly (Anyone, even anonymous) with a doPost method as follow,
function doPost(e){
var sheet = SpreadsheetApp.getActiveSheet();
var length = e.contentLength;
var body = e.postData.contents;
var jsonString = e.postData.getDataAsString();
var jsonData = JSON.parse(jsonString);
sheet.appendRow([jsonData.title, length]);
var MyResponse = "works";
return ContentService.createTextOutput(MyResponse).setMimeType(ContentService.MimeType.JAVASCRIPT);
}
When I sent a Post request with a JSON object with Advanced Rest Client it all works and return a 200 OK response. But when I try to send a post request with the react axios from a locally hosted react app it sends a 405 Response.
XMLHttpRequest cannot load https://script.google.com/macros/s/AKfycbzyc2CG9xLM-igL3zuslSmNY2GewL5seTWpMpDIQr_5eCod7_U/exec. Response for preflight has invalid HTTP status code 405
I have enabled cross origin resource sharing in the browser as well. The function that sends the POST request is as follow,
axios({
method:'post',
url:'https://script.google.com/macros/s/AKfycbzyc2CG9xLM-igL3zuslSmNY2GewL5seTWpMpDIQr_5eCod7_U/exec',
data: {
"title": 'Fred',
"lastName": 'Flintstone'
}
}).then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
You missed the important part:
Response for preflight has invalid HTTP status code 405.
Your browser is making a preflight request, which uses the OPTIONS HTTP method. This is to check whether the server will allow the POST request – the 405 status code is sent in the response to the OPTIONS request, not your POST request.
A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood. Source
Additionally, for HTTP request methods that can cause side-effects on server's data (in particular, for HTTP methods other than GET, or for POST usage with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method. Source
Some requests don’t trigger a CORS preflight. Those are called "simple requests" in this article [...] Source
This article section details the conditions a request has to meet to be considered a "simple request".
[...] "preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. Source
This article section details the conditions which cause a request to be preflighted.
In this case, the following is causing the request to be preflighted:
[...] if the Content-Type header has a value other than the following:
application/x-www-form-urlencoded
multipart/form-data
text/plain
The value for the Content-Type header is set to application/json;charset=utf-8 by axios. Using text/plain;charset=utf-8 or text/plain fixes the problem:
axios({
method: 'post',
url: 'https://script.google.com/macros/s/AKfycbzyc2CG9xLM-igL3zuslSmNY2GewL5seTWpMpDIQr_5eCod7_U/exec',
data: {
title: 'Fred',
lastName: 'Flintstone',
},
headers: {
'Content-Type': 'text/plain;charset=utf-8',
},
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
Another way for someone who has this problem in the future:
(in my case, using 'Content-Type': 'text/plain;charset=utf-8' doesn't work)
According to this doc https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format
Instead of using text/plain;charset=utf-8 as the accepted answer, you can use application/x-www-form-urlencoded:
const axios = require('axios')
const qs = require('qs')
const url = 'https://script.google.com/macros/s/AKfycbzyc2CG9xLM-igL3zuslSmNY2GewL5seTWpMpDIQr_5eCod7_U/exec'
const data = {
"title": 'Fred',
"lastName": 'Flintstone'
}
const options = {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: qs.stringify(data),
url
}
axios(options)
.then(function(response) {
console.log(response.data)
})
.catch(function(error) {
console.log(error)
})
I think you need to return JSON data. It is possible that you need to return JSONP to a request from a browser, but here is what I think you need to do:
return ContentService.createTextOutput(JSON.stringify({message: MyResponse})).setMimeType(ContentService.MimeType.JSON);
If that doesn't work, it is probably that you need to return JSONP to run in the browser. Here is some documentation to help you out: https://developers.google.com/apps-script/guides/content#serving_jsonp_in_web_pages