Why does Angular HttpClient replace "\n" with "↵" - json

Sending a POST body with the HttpClient that either is a string or is an object that has a string as a value will replace any occurrence of "\n" with "↵". This is primarily happening in Chrome 73. In firefox, it seems that "↵" appears as " " when viewing the Network call in the Inspector.
I've tried using JSON.stringify and JSON.parse and replacing "↵" with "\n" to no avail.
Stackblitz: https://stackblitz.com/edit/angular-uzxank
I expect the POST request body found shown in the browser's inspector to use "\n" and not "↵".

That's not particular to Angular's HTTP Client. That's merely how Chrome formats the display of line breaks within strings.
Check the demo below.
document.getElementsByTagName('button')[0].onclick = () =>
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: JSON.stringify({
title: 'title',
body: 'foo\nbar',
userId: 1
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => response.json())
.then(json => console.log(json))
Open Dev Tools. Then click:<br>
<button>click me</button><br>
Now check the HTTP call (the one with 201) in the networks tab<br>
Notice the line break is still shown as "↵" in Chrome.<br>
Notice also that the "\n" is properly transmitted, as shown by the response object's "body" field.

Related

Using PATCH method in html form

How to use PATCH method in an html form to send data to a server?
I've already done this
Html
<form class="type-title" method="POST" id="alter">
<input type="hidden" name="_method" value="PATCH"/>
<input id="alter" type="text" name="alter"/>
<button onclick="alter_name();">update</button>
</form>
JS
function alter_name(){
fetch("http://127.0.0.1:3000/api/member", {
method: 'PATCH',
headers: {
'Content-type' :'application/json'
},
body: {
"name":alter_name.value.toString()
}
}),then((response) =>{
return response.json();
}).then((data) =>{
console.log(data);
})
}
but it still not work
The main issue is how you have addressed the input value. Your form's id: id="alter" is the same name as the input which is invalid, but in your script you are not referencing this field correctly at all, lets fix all this...
Firstly with the HTML form, do not post back as that might affect other workflows on the form. We do this by forcing the button to act as a simple standalone HTML Button instead of being the submit button for the form. Do this by setting the type attribute of the button to "button":
_I've also changed the Id of the form to be unique and removed the _method hidden input.
<form class="type-title" id="alter_form">
<input id="alter" type="text" name="alter"/>
<button onclick="alter_name();" type="button">update</button>
</form>
You were on the right track with using javascript and fetch() to send the data as your API is not likely to be setup to accept form-data if you are using PATCH as the method on a standard form submit.
The other fix is in the script itself, we need to deliberately stringify the object payload that we sent in the body, this way we can control or enforce the serialization instead of relying on javascript, we can also more easily inspect the contents when or if it goes wrong.
Notice how the field is referenced using the path formId.fieldId.value
The other issue you had was that your JSON object wasn't formed correctly, you had quotes around the property name, which would have resulted in quotes being escaped and encoded into the JSON string value, which we don't want.
Finally, I've specified the encoding in the Content-Type as it was required on my system to parse the content on the server side.
function alter_name(){
let content = {
Details: alter_form.alter.value.toString()
};
fetch("http://127.0.0.1:3000/api/member", {
method: 'PATCH',
headers: {
'Content-type': 'application/json; charset=UTF-8',
'Accept': 'application/json'
},
body: JSON.stringify(content)
}).then((response) => {
console.log('PATCH Response.status: ', response.status);
if(response.status !== 204)
return response.json();
else
return response.statusText;
}).then((data) => {
alert(data);
});
}
For a few bonus points, I've added some handling for a 204: No Content response from the server. Many PATCH implementations do not return content unless you explicitly request it with a Prefer HTML Header.

Is there a way to partial respond with Puppeteer or the devtools protocol request interception?

The main problem i am facing is that
await page.setRequestInterception(true);
page.on('request', request => {
request.respond({
status: 404,
contentType: 'text/plain',
body: 'Not Found!',
});
});
examples to always contain body as complet buffer or string but i need to stream the body.
i did find some classes that indicate that this is possible for example https://pptr.dev/api/puppeteer.httprequest.respond states always that this could be a Partial<Response....>
but i did not get it working to intercept and respond multiple times

Axios post request returns data instead of rendering an error page

I have this post request:
axios({
method: "post",
url: "/sessions/add",
data: {
session: {
name: session.session.name,
date: sessionDateInput.value,
},
},
})
//redirect back to sessions/add
.then((res) => console.log(res))
.catch((err) => console.log(err.response.data));
It works fine if all the post data is correct, however, if it is not correct I have an error page in my "views" directory set up,
with that said, my express server isn't able to render res.render('errorPage')
and instead of rendering the error page, throws an error in the console.
the post request works fine if I use the html and it is able to res.render:
<form method="post" action="/route"></form>
the error page:
any way to fix this?
Since the response contains a html-document in case of an error, you could replace the current document with its content, e.g.:
//...
.catch((err) => document.write(err.response.data));

How to fix: "SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data"

I'm working with React-Native right now, trying to pass formdata to a backend php-file as JSON. But everytime the form is submitted the console shows the following error "SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data". With firefox I checked the request and response under network.
Under request it shows the JSON correctly, under response it shows the JSON correctly. 1 thing that stands out is that under Headers, it says that response Content-Type is text/html and that request Content-Type is text/plain. Could that be causing the issue? I wouldn't know what else to do since I already specify the Content-Type in the code.
Google Chrome says .then(response => response.json()) is causing the error.
await fetch('http://192.168.2.16/React-Native/endpoint.php', {
method: 'POST',
header: {
'Accept': 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify({
intensiteit: intensiteit,
soortStank: soort,
latitude: lat,
longitude: long,
buurt: neighbourhood,
}),
mode: 'no-cors',
})
.then(response => response.json())
.then(responseJson => {
Alert.alert(JSON.stringify(responseJson));
})
.catch(error => {
console.error(error);
});
The php-file:
$obj = file_get_contents('php://input');
$obj = json_decode($obj, true);
$result['soort'] = $obj['soortStank'];
echo json_encode($result);
And yes I looked at other posts, but they didn't help sadly. I also tried adding dataType: 'json', in there, but that didnt help.
The request from your front-end app to the back-end endpoint is a cross-origin request. Adding mode: 'no-cors' to the fetch request doesn't change this, so remove it to begin with.
Next, the php endpoint must include some header declarations to allow the cross-origin request to succeed.
Add the following to the top of the php file, replacing the http://localhost:9999 part with the origin you are sending the request from. When testing locally, it'll likely be identical apart from the port number. When running in production, be sure to replace it with the correct origin for your front-end app eg. https://www.example-app.com.
header("Allow-Access-Control-Origin: http://localhost:9999");
header('Content-Type: application/json');
This should work.
This is likely a problem of null values.
Replace null values with empty strings in the body.
Perhaps, you also just need to change the php file to:
$obj = file_get_contents('php://input');
$obj = json_decode($obj, true);
$result['soort'] = $obj['soortStank'] ?? '';
echo json_encode($result);

JSON Parse error: Unrecognized token '?' in React Native

I am working on React Native project and I try to transform datas from a server to JSON.
I have already done it on other projects, so I know how it works, but this time I have an error :
"JSON Parse error: Unrecognized token '<' ".
Here is my code :
fetch('https://app.fr', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
}),
})
.then((response) => response.json())
When I do response.text() instead, I get a string which is a correct JSON format. So I know the datas are not the problem.
fetch('https://app.fr', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
}),
})
.then((response) => response.text())
After looking on forums, I found that the error could be that the server send me datas whith content-type "text/html" instead of "application/json". And yes, the server send me datas with content-type "text/html".
So I tried to change the content-type in the header:
fetch('https://app.fr', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json',
}),
})
.then((response) => response.json())
But I got that error : "JSON Parse error: Unrecognized token '?' "
So I thought it means that I need to change directly the content-type of datas on the server. But I can't do it because my client is using these datas for others projects.
Do yo know any possibility to transform to JSON datas with "text/html" content-type, without getting this kind of error?
Thanks !
I have found the problem !
In the datas client send to me, there was an invisible first character.
When I was rendering it on my phone I saw "{"message":"ok","testes":...} but when I log it in my console I saw that there was a strange character before the first "{".
I deleted it with response.text().substring(1) and it works !
Thanks for your answers !