Aurelia fetch client: 404 for POST with JSON body - json

I'm trying to post request with JSON body using aurelia fetch client. Here is my code:
import {inject, NewInstance} from 'aurelia-framework';
import {HttpClient, json} from 'aurelia-fetch-client';
#inject(NewInstance.of(HttpClient))
export class TestClass {
constructor(httpClient) {
this.__httpClient = httpClient.configure(x => {
x.useStandardConfiguration()
.withBaseUrl('http://test.com/api/')
});
}
sendRequest() {
let test= {
paramone: 'One',
paramtwo: 'Two'
};
this.__httpClient.fetch('postdata', {
method: 'post',
body: json(test)
});
}
}
However I get the following error in browser console:
Fetch API cannot load http://test.com/api/postdata. Response for preflight has invalid HTTP status code 404
The problem is that if I don't send json body (i.e. body: '') the request reaches the server! So, there's some issue with the body. Could you please help me to find out the root cause?

Related

NestJS - accepting multiple MIME types in request body

I am trying to create an endpoint in a HTTP API that receives data periodically from remote devices.
There is a technological shift happening in this project where devices have previously reported data in XML whereas future implementations will shift towards JSON.
I am writing this API in NestJS (7.x) and TypeScript. Data will be coming in through the same endpoint (POST /) and data format is differentiated by the Content-Type header.
#Controller()
export class IngressController {
constructor(private readonly ingressService: IngressService) {
}
/* ... */
#Post('')
#Header('Cache-Control', 'none')
#HttpCode(HttpStatus.NO_CONTENT)
public async receive(
#Headers('Content-Type') contentType: string,
#Req() req: any,
#Body() body: string,
): Promise<InsertResponse> {
if (IngressController.isJson(contentType)) {
return { inserted: await this.ingressService.insertJsonString(req.body) };
}
if (IngressController.isXml(contentType)) {
return { inserted: await this.ingressService.insertXmlString(req.body) };
}
throw new BadRequestException(contentType, 'Unsupported Content-Type');
}
/* ... */
}
Future devices will report data in JSON (indicated by the Content-Type: application/json header in the HTTP request), legacy devices report in XML (Content-Type: application/xml).
It works splendidly for JSON. However, my problem is that req.body (or body respectively) is an empty object in the XML case. I presume the NestJS middleware is doing something and getting confused by XML, but I have found no hints as to allow XML payloads side-by-side with JSON. I don't mind parsing it manually.
As you suspected NestJS has a built-in bodyparser that will not be able to parse xml. What you could do is to plug in a custom middleware where you decide whether to parse the request body as xml or pass the request on the the next handler.
Something like this should work (I'm using express-xml-bodyparser in this example):
import {NestFactory} from '#nestjs/core';
import {AppModule} from './app.module';
import {Request} from "express";
const xmlParser = require('express-xml-bodyparser');
const xmlParserMidleware = xmlParser();
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use((req: Request, res: any, next: any) => {
if (req.path.includes("/api/json-or-xml-handler") && req.header('Content-Type')?.includes('xml')) {
return xmlParserMidleware(req, res, next);
}
next();
});
await app.listen(8020);
}
bootstrap();
Then, in your controller body will either be the parsed json-object or an object representation of your xml:
#Controller()
export class TestControllerController {
#Post('/api/json-or-xml-handler')
receive(#Body() body: any) {
console.log(body);
// ...
}
}

HttpClient.post is sucessful but not sending data to json

I am trying to store data from my angular app into a JSON. The JSON is stored within the assets folder of my app and I have the app on a server.
I am using HttpClient to POST data to the JSON. It says it is successful but it does not actually send the data.
This is my .ts:
import { HttpClient } from '#angular/common/http'
import { HttpHeaders } from '#angular/common/http'
export class OpscreenComponent implements OnInit {
constructor(private httpService: HttpClient ) { }
ngOnInit() {
var jsonpost = {
"testing": [
{
"anothertest":"here",
"anumber": 1
}
]
}
var headers = new HttpHeaders({
'Content-Type': 'application/json'
})
var options = { headers: headers }
this.httpService.post("http://servername/angularApp/assets/testing.json", jsonpost, options)
.subscribe(
data=> {
console.log("POST Request is Successful ", data )
},
error => {
console.log("Error ", error)
}
)
}
}
I get no error messages and the request is successful because it is logging POST Request is Successful null in the console.
The json is blank to start and after the POST success it is still blank (hence the null in the console.)
Why is it not posting the data to the JSON?
I am using httpClient for get so I know it is imported correctly.
this.httpService.request('POST', `${YourTestUri}`, { body: jsonpost, headers: headers }).pipe( switchMap( (response: any) => ... ) );
What you are trying to do is write files to disk, unfortunately, The HttpClient of Angular can't write files to disk. At least not with the classic implementation.
You probably prefer to add a server who can write to the disk, and your HttpClient will hit the server with the corresponding data.

Sending json data to backend via HTTP POST in Ionic 4 not working. [Notice: Trying to get property of non-object]

I try to send http request via http post in Ionic 4 to my PHP backend through URLhttp://myexamplehost#1.com/api and it gives me back Notice : trying to get property of non object....
When i send my json data through URL http://myexamplehost#1.com/api via postman it works just fine. I'm guessing my json data sent via http post in Ionic 4 is somehow wrong.
So i try to send my json data through my other URL https://myexamplehost#2.com/api via http post in Ionic 4 and long behold it works just fine.
Here's what the json i sent via postman :
{
"id": "",
"date": "2019-09-09",
"name": "jason"
}
And here's what i sent via http post in Ionic 4 page.ts:
mydata: Idata = {
id:string;
date:string;
name:string
}
saveData(){
this.dk.insertData(this.mydata).subscribe((result:any)=>{
console.log(result['_body']);
});
}
Here's what the service method look like :
insertData(data:Idata){
return this.http.post(this.configUrl+'?ins=true',data,{
headers: { 'Content-Type': 'application/json',
'Accept': 'application/json',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT'
}
});
Here's what the backend look like :
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
print_r(json_encode($request));
// echo json_encode($request->name."-".$request->date);
// echo json_encode($request->tgl);
$result = $obj->insData("example_tb","null,'".date('Y-m-d',strtotime($request->date))."','".$request->name."'");
So what i really want to know is that is it a CORS issues or is it a code issues in my situation right there? Because i do get an error message of origin has been blocked by CORS policy in a console though. How do i fix this issues?
I would like to point that Access-Control-Request-Method is a request header that is set by the browser on CORS preflight requests, and it can only have one value.
Where The Access-Control-Allow-Methods is a CORS response header, returned by backend.
Replace
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT'
With
'Access-Control-Request-Method': 'POST'
Below code works for Ionic 4.
app.module.ts
İmport HttpClientModule
import { HttpClientModule } from '#angular/common/http';
Add HttpClientModule to imports.
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [HttpClientModule],
Now on your other page.
Mine ucak.page.ts
import { HttpClient } from '#angular/common/http';
constructor(public http: HttpClient) {}
SendDataFu(){
let postData = {
user: "doctoravatar#yahoo.com",
t: "vlIj",
zip: 94089,
forecast: 7
}
this.http.post("https://json.penzance.org/request", postData,{observe: 'response'})
.subscribe(data => {
console.log(data);
}, error => {
console.log(error);
});
}

Is there a way to skip preflight response not processed by Angular httpClient?

We are developing an Angular 6 app using httpClient and with withCredentials: true. When we are making a request to another port on the same server (from port 8010 to 8011), Firefox tries to make a preflight request. But it seems like our angular httpClient is trying to process this preflight response. We are using the below code. And we see that, the flow is entering the catchError block. Why is angular-httpclient prcessing preflight response? How do we handle this?
request(url: string, method: string, options?: any, xmlOptions?: any,
isFullUrl:boolean = false): Observable<any> {
const fullUrl = (isFullUrl) ? url : `${HttpService.BASE_URL}${url}`;
return this.httpClient.request(method, fullUrl, options).pipe(
map(resp => this.parseXML(resp, xmlOptions)),
catchError(exception => this.processError(exception, xmlOptions))
);
}
private processError(exception, xmlOptions) {
this.notificationService.clear();
this.notificationService.error(HttpService.UNEXPECTED_ERROR_OCCURRED);
if(exception.error) {
let errorObj = this.parseXML(exception.error, xmlOptions);
return throwError(errorObj);
}
else {
return throwError(exception);
}
}
If we inspect the exception, the error message is "Http failure response for (unknown url): 0 Unknown Error"
Note: This is working fine in Chrome browser.

Empty reponse body Http Angular 2 with status 200

I'm working with Angular2 for front-end developpement and Scala play framework for back-end.
My problem is that the back-end send the Json I need, tested with Postman it works, but it seems that angular doesn't receive anything in body.
Client.ts
public static getAllUncompleteCompanyForm(http: Http, userId: string, headers: Headers, apiUrl: string): Observable<Response> {
return http.get(apiUrl + Client.version + 'scoring/uncomplete-form/companies/' + userId, {headers: headers});
}`
CompanyFormService.ts
getAllUncompleteCompanyForm(userId: string) {
let headers = getHeader(this.token());
return Client.getAllUncompleteCompanyForm(this.http, userId, headers, environment.backendUrl).subscribe(response => {
console.log(response);
},
error => console.log(error));
}
Here's the log :
What am I doing wrong ?
EDIT
When I use response.json() I get this :
Unexpected end of JSON input
EDIT 2
Content type of response header is text/plain. Maybe that's a lead for something ? However when I send application/json the result is the same there's nothing in the body