Angular HTTP post not accepting JSON response? - 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

Related

Wordpress REST API ignoring POST request from Google Apps Script when using 'Body'

I am fiddling for the first time with REST APIs so my knowledge is very low.
I am using Google Apps Scripts to manage Wordpress data through REST API.
POST Requests are perfectly working when options are passed through the URL parameters, while they are ignored when using body.
I initially thought that this was due to some issues on the Wordpress endpoints, however, as sending requests using Postman the calls are being processed correctly, I suppose data is being sent incorrectly from my Google Apps Script.
Postman will expose sent data, offering an option to generate code for a given language, therefore I have used Javascript Fetch as a starting point.
Following is the Postman-generated code, which is correctly processed by Wordpress:
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer some-token-here");
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Cookie", "wordpress_google_apps_login=some-cookie-data-here");
var raw = JSON.stringify({
"acf": {
"class": "Nursery"
}
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://example.com/wp-json/wp/v2/users/442?context=edit&_fields=acf", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
With the above as a starting point, I have adapted code for Google Apps Script, as follows:
var raw = JSON.stringify({
"acf": {
"class": "Nursery"
}
});
var requestOptions = {
'method': 'POST',
'headers': {'Authorization' : 'Bearer some-token-here',
'Content-Type' : 'application/json'},
'body': raw,
'redirect': 'follow'
};
var response = UrlFetchApp.fetch("https://example.com/wp-json/wp/v2/users/442?context=edit&_fields=acf",requestOptions);
Google Apps Script will return a response with code 200, but the requested modifications will not occur. Please notice that the code generated by Postman, uses 'Content-Type', while Google Apps Script should use 'ContentType' parameter. I have tried both, with no success.
Are there some errors in the adapted code, or is there something missing, or even worst, Google Apps Script has some limitations or is it changing somehow the POST request in a way it is not correctly interpreted on the Wordpress end?
EDIT
A quick addition to #idfurw solution, is that it is also required to use 'Content-Type', as the request which includes 'ContentType' will be ignored!
To post the body, use payload property instead of body property.
Reference:
examples of fetch(url, params)
Advanced parameters

Angular failed post request with error 500

I am developing an ionic app that makes a rest call to a backend to send an email, when I make the rest call I get the following error, what can be due to (the rest call in postman works, I use chrome with the cors disabled)
Error:
POST http://172.16.50.92/send 500 (Internal Server Error)
Code Angular:
const params = {
'type': 'mail',
'attributes[to_recipients]': mail,
'attributes[body]': body,
'attributes[subject]': subject,
'attributes[attachments]': attachments
};
endpoint = url + '/send';
var headers_object = new HttpHeaders();
headers_object.append('contentType', 'application/json');
headers_object.append('Authorization', `Basic ${window.btoa(username + ':' + password)}`);
return this.http.post(endpoint, params, [headers_object]);
return this.http.post(endpoint, params, [headers_object]);
You put your headers into an array. But the signature is supposed to be
post(url: string, body: any, options: { headers: HttpHeaders })
for your usecase.
Please change to below and try again.
return this.http.post(endpoint, params, { headers: headers_object });

send post from webpage to Node.js server ...do not use 'fetch'...?

I am using the following javascript on a webpage to send information to a Node.js server upon a "click" on an image. This is using a 'POST' request.
<script>
function rerouter(_sent) {
var _people = <%- JSON.stringify(member_list) %>;
//convert the passed ('member_list') array into a JSON string...
var _attend = <%- JSON.stringify(online) %>;
//convert the passed ('online') array into a JSON string...
var splits = _sent.id.split("_"); //"split" on "underscore ('_')"
if (_people.indexOf(splits[1]) != -1) {
//**SEND INFO TO SERVER...
var available = _attend[_people.indexOf(splits[1])];
var response = fetch("members/pages/:" + splits[1] + "/presence/:" + available, {
method: 'POST',
headers: {
'Content-Type': 'text/plain;charset=utf-8'
}
});
//**
} //'_people' array contains the member name ('splits[1]')...
}
</script>
And here I handle the request in my Node.js server code:
var bodyParser = require('body-parser')
// create application/json parser
var jsonParser = bodyParser.json()
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.post('/members/pages/:membername/presence/:online', urlencodedParser, function (req, res) {
console.log("I RECEIVED FROM CLIENT THE FOLLOWING:")
console.log(req.params)
console.log(req.body)
res.redirect('/_landing');
})
Here is my console output:
I RECEIVED FROM CLIENT THE FOLLOWING:
{ membername: ':Nica', online: ':Yes' }
{}
As can be seen from my output, the POST route does seem to be functional, somewhat. However my 'redirect' command does NOT execute...the webpage does not change to the '_landing' page as it should...I think it may be because I am using 'fetch' to send the POST request...??? Can somebody verify if that is the cause (or another issue is the cause) and how I might be able to correct the issue?
In addition why does my 'params' include the colons (":") when I log to the console...is that standard? I would not think it would include the colons in the log, only the actual data.
Basically it seems my POST is almost working...but not exactly. Any suggestions would be greatly appreciated. I thank you in advance.
UPDATE: I have made some changes and my POST seems to be working fine now. In my frontend webpage I use the following to make the HTTP POST request:
<script>
function rerouter(_sent) {
var _people = <%- JSON.stringify(member_list) %>;
//convert the passed ('member_list') array into a JSON string...
var _attend = <%- JSON.stringify(online) %>;
//convert the passed ('online') array into a JSON string...
var splits = _sent.id.split("_"); //"split" on "underscore ('_')"
if (_people.indexOf(splits[1]) != -1) {
//**SEND INFO TO SERVER...
var available = _attend[_people.indexOf(splits[1])];
fetch('/members/pages/callup', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({name: splits[1], presence: available, str: 'Some string: &=&'})
})
//**
} //'_people' array contains the member name ('splits[1]')...
}
</script>
...And modified my route handler in my Node.js script:
// create application/json parser
var jsonParser = bodyParser.json()
app.post('/members/pages/callup', jsonParser, function (req, res) {
console.log("I RECEIVED FROM CLIENT THE FOLLOWING:")
console.log(req.body)
res.redirect('/_landing');
})
This is functional...to receive the data sent from the frontend webpage.
The only remaining problem is why does the 'redirect' not fire...??? I still have a feeling that by using a 'fetch' that somehow this is interfering with the page redirection...? A fetch would normally be used to wait for a response from the server, in my case I am not interested in that functionality I just want to send data one-way from frontend to backend...and then redirect the frontend page. I cannot think of any other reason why the redirect does not fire...?
Make extented:true instead of false as,
var urlencodedParser = bodyParser.urlencoded({ extended: true }) and move this line above of the below statement,
var jsonParser = bodyParser.json() and check if it works.
And finally change your headers here from,
headers: {
'Content-Type': 'text/plain;charset=utf-8'
}
To,
headers: {
'Content-Type': 'application/json'
}
Hope this will resolve the issue.

Easy way to Post HTTPS JSON data (header+body) using Node.js

After reading multiple internet posts related to "JSON POST commands" in NodeJS I'm now totally lost! Have tried to create an easy script to send data to a device Restful API interface using https. Without any luck...
JSON string needs to contain: a Header incl. (Basic)Auth Token & Body
content something similar like:
'{"address":address,"address6":"","comment":"","duids":[],"hostnames":[],"interface":""};
Hoping that someone has a good example available or can point me into right direction again.
You can use in-built module https to make a REST API call, the request signature is as follows:
https.request(url[, options][, callback])
In your case, you can try following code:
var options = {
host: 'host-name',
port: 443,
path: 'api-path',
method: 'POST',
// authentication headers
headers: {
'Authorization': 'Basic ' + new Buffer(username + ':' + passw).toString('base64')
}
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
I had the exact same issue just few days ago, and I've ended up creating a super tiny module called json-post.
const jsonPOST = require('json-post');
// or import jsonPOST from 'json-post'
jsonPOST(
'https://whatever:5000/seriously',
// your JSON data as object
{hello: 'world'},
// optionally any extra needed header
{'Authorization': 'Basic ' +
new Buffer(username + ':' + passw).toString('base64')}
).then(
console.info,
console.error
);
The dance is similar to the one shown in the previous reply but it's simplified in various ways. It works well for GitHub OAuth and others services too.
I always use request library whenever I need to do HTTP request in nodejs.
var request = require('request');
request({
method: 'POST',
uri: 'http://myuri.com',
headers: {
'Content-Type' : 'application/json',
'AnotherHeader' : 'anotherValue'
},
json: myjsonobj
}, (err, response, body) => {
// handler here
})
there are other ways of making the request as well like request.post() refer here

App Script sends 405 response when trying to send a POST request

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