Encoding issue with Axios - character-encoding

I am fetching a web page with axios, but the content-type of the response is ISO-8859-1, and the result given by axios seems like it parses it as UTF-8 and the result has corrupt characters.
I tried to convert the result encoding but nothing works, and I think it does not because of this
For example in the got library I can set encoding to null and overcome the problem, but I would like to ask you what can I do with axios to disable the auto-encoding or change it?

My approach was this:
Make the request with responseType and responseEncoding set as below
const response = await axios.request({
method: 'GET',
url: 'https://www.example.com',
responseType: 'arraybuffer',
responseEncoding: 'binary'
});
Decode reponse.data to the desired format
let html = iso88592.decode(response.data.toString('binary'));
Note: In my case, I needed to decode it using this package.

Without using interceptor or another package, I got the response on a buffer with:
notifications = await axios.request({
method: 'GET',
url: Link,
responseType: 'arraybuffer',
reponseEncoding: 'binary'
});
And next converting it with:
let html = notifications.data.toString('latin1');

In this github issue Matt Zabriskie recommends using an axios response interceptor, which I think is the cleanest option.
axios.interceptors.response.use(response => {
let ctype = response.headers["content-type"];
if (ctype.includes("charset=ISO-8859-1")) {
response.data = iconv.decode(response.data, 'ISO-8859-1');
}
return response;
})

const notifications = await axios.request({
method: 'GET',
url: 'https://...your link',
responseType: 'arraybuffer',
reponseEncoding: 'binary'
});
const decoder = new TextDecoder('ISO-8859-1');
let html = decoder.decode(notifications.data)

Related

nSwag change responseType: "blob"

I have a problem. I am using asp.net core 3 web api. The Angular 8 app client is generated with nSwag version 13.2.1.0. The specificatio is generated Swashbuckle.AspNetCore 5.
The result I get is:
**
* #param body (optional)
* #return Success
*/
seller(body: RegisterSellerRequest | undefined): Observable<TokenResponse> {
let url_ = this.baseUrl + "/api/register/seller";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
let options_: any = {
body: content_,
observe: "response",
responseType: "blob",
headers: new HttpHeaders({
"Content-Type": "application/json-patch+json",
"Accept": "application/json"
})
};
As you can see the responseType: "blob" is generated, and that's not good for our angular app's interceptor.
Is there a way to set response to be application/json?!
In my controllers I set the swagger attributes like this:
[ApiExplorerSettings(GroupName = Constatns.PublicSwaggerGroup)]
[SwaggerOperation(OperationId = "registerSeller")]
[HttpPost("api/register/seller")]
[ValidateModel]
[AllowAnonymous]
[ProducesResponseType((int)HttpResponseType.OK, Type = typeof(TokenResponse))]
[ProducesResponseType((int)HttpResponseType.BadRequest)]
[Produces("application/json")]
public async Task<TokenResponse> RegisterSeller([FromBody] RegisterSellerRequest data)
{}
I think its currently no simple way to change that. Its the simplest way to load everything as blob and then transform it to json or binary depending the response type. Changing that would mean that the generator templates get much more complicated.

How to Http Post with Json Body on Flutter

I am trying to get data from API. I need to pass value from the body, in postman without a header: application/JSON data is not displayed.
final response = await http.post(
"http://192.168.10.25:8080/Login/validateusername",
body: {"username": "user#PYA"},
headers: {'Content-Type': 'application/json'},
);
Error Message:
E/flutter (28851): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter (28851): Bad state: Cannot set the body fields of a Request with content-type "application/json".
Add the content type application/json
Future<String> apiRequest(String url, Map jsonMap) async {
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
// todo - you should check the response.statusCode
String reply = await response.transform(utf8.decoder).join();
httpClient.close();
return reply;
}
Simply encode body to json object when using content-type "application/json"
http.Response response = await http.post( uri , headers: headers, body: JsonEncoder().convert(body));
Another simple way is as bellow
import 'package:http/http.dart' as http;
String body = json.encode({
'foo': 'bar',
'complex_foo' : {
'name' : 'test'
}
});
http.Response response = await http.post(
url: 'https://example.com',
headers: {"Content-Type": "application/json"},
body: body,
);
use the http dart package
var data = {username:"username",password:"password"};
http.Response response = await http.post(
"yourApiroute",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: {"username": data.phone, "password": data.password});
var json = jsonCodec.encode(data);
print("json=$json");
var url = "http:yourAPIrouter.com/etc";
var response = await http.post(
url,
headers:{ "Accept": "application/json" } ,
body: { "json": '$json'},
encoding: Encoding.getByName("utf-8")
);
and dont forget add the key "json" in postman
I am doing almost the same. However, I tried to avoid doing back-end, like in your case. I just did a minimal php request so that I would not waste or patience learning what is needed to develop a user management controller.
However, I faced several limitations and problems that Flutter alone can't solve. After some denial, I gave a try. Lumen, a light version of the Laravel Framework, some tutorials and some past experience, I eventually realized that the API should carry most of the authentication, and not the application itself. I digressed.
In my case, the code of the fuction to a http post is:
Future<Post> createPost() async {
final url = "http://localhost:8000/api/login";
Map<String, String> body = {
'user': user.text,
'pass': pass.text,
};
await http.post(url, body: body);
print(body);
return http.;
}
I first convert it into a map. I prefer this method over parsing json, because down the line, if I need to add more variables, I just make the map bigger.
I just have a question: What does your http://192.168.10.25:8080/Login/validateusername look like? I think that there is no need to specify the type of information that your body parses.

How to get a file using fetch in 'Code by Zapier'

I was requesting an API that delivers pdf. This also need authorization.
var fileUlr = 'https://api.safetyculture.io/audits/1234/exports/5678.pdf';
var getFile = fetch( fileUlr, { method: 'GET', headers: { 'Authorization': 'Bearer 2034weoiroew' } } )
.then( function( fileBinary ) {
return fileBinary;
});
I am getting the file in binary format. How to convert this to original pdf? Then I need to programmatically upload the file to dropbox/google drive. Can you help me?

Delete entry from database with WinJS and OData

I'm trying to delete an entry from the database by odata. I get the error message
{"error":{"code":"","message":{"lang":"en-US","value":"Bad Request - Error in query syntax."}}}
my code:
function deleteMonthEntry() {
var item = actMonthEntries.getItem(listIndex);
var queryString = "Stundens(" + item.data.datensatz_id + ")?$format=json";
var requestUrl = serviceUrl + queryString;
WinJS.xhr({
type: "delete",
url: requestUrl,
headers: {
"Content-type": "application/json"
}
}).done(
function complete(response) {
},
function (error) {
console.log(error);
}
);
}
My request URL looks like this:
requestUrl = "http://localhost:51893/TimeSheetWebservice.svc/Stundens(305233)?$format=json"
Thanks
Marlowe
At least I found the solution:
I've entered an filter request to my service like this:
TimeSheetWebservice.svc/Stundens?$filter=datensatz_id eq 305221
this returned the correct entry with this link:
TimeSheetWebservice.svc/Stundens(305221M)
So if I enter a M after the ID, everything works fin. But I have no idea where this M comes from.
Can anyone tell me the reason for this M? It does not belong to the ID. The ID is this
305221
Marlowe
Are you sure the server you're talking to supports the $format query option? Many don't. I would try removing that part of the request URI, and instead modify your headers value to specify an Accept header:
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
}
For servers where $format is allowed, giving it a json value is equivalent to providing an Accept header with the application/json MIME type.
In general, for a DELETE operation, the Accept header or $format value only matters for error cases. With a successful DELETE, the response payload body will be empty, so there's no need for the server to know about your format preference.

Xhrpost not hitting the controller(url)

I am trying to post data to mvc controller and i am unsuccessful doing so..hope i get any help...here is the xhrpost call
var reqObj =
{
Id: dojo.byId("Id").value,
Password: dojo.byId("Password").value
};
console.log(reqObj );
var xhrArgs = {
url: '~/FormController/ValidateRequest',
postData: reqObj ,
handleAs: "json",
headers: { "Content-Type": "application/json", "Accept": "application/json"},
load: function (data) {
alert(data);
}
}
var deffered = dXhr.post(xhrArgs);
console.log(deffered);
}
I could not even see a post call in firebug....what might be the problem..any clues?
Thanks in advance.
I see a couple issues:
First you populate reqObj with the values you want to post, however, you put "request" into your xhrArgs.
Second, you will need to convert reqObj to json (dojo.toJson), since you are handling the post as json.
Also, I don't see a reference to the dojo.xhrPost method? Are you using sometype of framework that encapsulates that?

Resources