HTTP 200 and null response in Chromium >=94 - google-chrome

After my locally installed browsers (Edge Chromium and Google Chrome) were updated to a version with Chromium >=94 fetching large files do fail.
I tested with two implementations, Fetch and XmlHttpRequest. In both implementations the HTTP status and response are the same. In browsers with Chromium version 93 the expected response is returned. When running the same code in browsers with Chromium versie 94, i do get a HTTP 200, but response is always null
Any idea if this is a specific Chromium 94 issue ?
return new Promise((resolve, reject) => {
var url = getBaseUrl() + serviceUrl;
fetch(url,{
method: "GET",
headers: {
importance: "low"
}
}).then((response) => {
if (response.status === 200) {
response.arrayBuffer().then(buffer => resolve(buffer))
} else {
reject(response);
}
})
});
and
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
var url = getBaseUrl() + serviceUrl;
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response);
} else {
reject(this.response);
}
};
xhr.send();
});

Related

How to pass image file to the body of Http request (POST) in Flutter?

I Took a variable in my State File? image;
Then Accesing image from my device
void filePicker() async {
final File? selectedImage =await ImagePicker.pickImage(source: ImageSource.gallery);
print(selectedImage!.path);
setState(() {
image = selectedImage;
});
}
Then tyring to pass the image file along with other http body parameters. If I didn't pass the image file, then the API didn't show any error. But I need to pass the image file to get the correct result.
As I Explicitly throw Exception, so its throwing exception like Faild to fetch and message in ScaffoldMessenger --> Somthing went wrong
Future<void> SaveCustomTestBooking() async {
var jsonResponse;
if (EncUserId.isNotEmpty) {
var postUri = Uri.parse("http://medbo.digitalicon.in/api/medboapi/SaveCustomTestBooking");
var request = http.MultipartRequest('POST', postUri);
request.fields['VisitDate'] = _selectedDate;
request.fields['EncUserId'] = EncUserId;
request.files.add(new http.MultipartFile.fromBytes('image',await File.fromUri(Uri.parse(image!.path)).readAsBytes(),contentType: new MediaType('image', 'jpeg')));
request.send().then((response) {
if (response.statusCode == 200) {
print("Uploaded!");
Navigator.push(context,MaterialPageRoute(builder: (context) => DieticianAfterDateSelectPage(rresponse:DieticianEncBookingIdModel.fromJson(jsonResponse),)));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("Somthing went wrong")));
throw Exception("Faild to fetch");
}
});
}
}
You should use MultiPart post method. Take a look at this.
You can pass image file simply in this way:
//header
var headers = {
'content-type': 'multipart/form-data',
'Accept': 'application/json',
};
//setup request
var request = http.MultipartRequest(
"POST", Uri.parse("your api url"));
//add files to reqest body
request.files.add(await http.MultipartFile.fromPath(
'your feild name',
pickedFile.path,
));
//add header
request.headers.addAll(headers);
//send request and return response
try {
var streamedResponse = await request.send();
var response = http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
rethrow;
}
}
Finally managed to slove it using Multipart.. Here is full API function code of mine
Future<void> SaveCustomTestBooking() async {
var jsonResponse;
if (EncUserId.isNotEmpty) {
var response = http.MultipartRequest('POST',Uri.parse("http://myApiTestBooking"));
response.fields['VisitDate'] = _selectedDate;
response.fields['EncUserId'] = EncUserId;
response.fields['Description'] = testTextController.text;
response.files.add(new http.MultipartFile.fromBytes(
"UserFile", File(image!.path).readAsBytesSync(),//UserFile is my JSON key,use your own and "image" is the pic im getting from my gallary
filename:"Image.jpg",
contentType: MediaType('image', 'jpg')));
response.send().then((response) async {
if (response.statusCode == 200){
isApiCallProcess = false;
final respBody = await response.stream.bytesToString();// this is how we print body for Multipart request
jsonResponse = json.decode(respBody.toString());
print(respBody);
print("Uploaded!");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Booked"),
backgroundColor: Color(0xFF00b3a4),
));
// Navigator.push(context,new MaterialPageRoute( builder: (context) =>new MyTestReqDetailsPage(),));
Navigator.push(context,new MaterialPageRoute( builder: (context) =>new Home2(),));
}
});
}
}

New Promise output returning the words "Promise { }"

I'm working in a code with Promise to get JSON values, the code is working, but the output aways return between the words Promise { }.
const info = new Promise((resolve, reject) => {
var req = require('request');
var options = {
url: 'https://api.info.com/',
headers: {
'User-Agent': 'request'
}
};
req(options, function (err, response, body) {
if (!err && response.statusCode === 200) {
resolve(JSON.parse(body));
}
});
});
console.log(info); //Output: Promise { [ { name: 'Gary'}, { name: 'John'} ] }
What I'm doing wrong?
I'd like my output was only as in the website:
[ { name: 'Gary'}, { name: 'John'} ]
==> UPDATE
It's works partially:
const info = new Promise((resolve, reject) => {
var req = require('request');
var options = {
url: 'https://api.info.com/',
headers: {
'User-Agent': 'request'
}
};
req(options, function (err, response, body) {
if (!err && response.statusCode === 200) {
resolve(JSON.parse(body));
}
});
});
info.then(function(value) {console.log(value)});//output: [ { name: 'Gary'}, { name: 'John'} ]
but, I need to use the result outside of then to perform others queries operations using this Json result, I tried something like that:
info.then(function(value) { jsonfile = value });
console.log(jsonfile);//Output: jsonfile is not defined
You're console.logging the promise object. If you want the data from the resolve action, you can chain a function that uses that data.
ex:
const info = new Promise((resolve, reject) => {
var req = require('request');
var options = {
url: 'https://api.info.com/',
headers: {
'User-Agent': 'request'
}
};
req(options, function (err, response, body) {
if (!err && response.statusCode === 200) {
resolve(JSON.parse(body));
}
});
});
//On resolve, perform some function to the returned value (This can be replaced with a function call)
info.then(function(value) {console.log(value)});
More examples and details can be found at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
Edit in response to comment (i don't have the rep to post comments): Promises are synchronous, while code not inside the promise or then() is not treated synchronously. This is worth mentioning because while you could a sign your value to a global variable or define your var 'value' before the promise, 'value' may not have been resolved by the promise yet, meaning you have introduced a race condition. Instead, if you need the data from your promise in another function (they need to run sequentially), that function should be invoked in your then().
Ex:
info.then(function(value){
otherfunction(value);
});
function otherfunction(val) {
//does whatever you need to value and will occur after the promise above resolves
}
info is a pending promise. You need to await of use .then on it
Sample code
const info = new Promise((resolve, reject) => {
var req = require('request');
var options = {
url: 'http://httpbin.org/get',
headers: {
'User-Agent': 'request'
}
};
req(options, function (err, response, body) {
if (!err && response.statusCode === 200) {
resolve(JSON.parse(body));
}
});
});
console.log(info); // Promise { <pending> }
info.then((result) => console.log(result)); // api result

HTTP request delayed in Chrome if dev tools not open

I'm working on a webpage in an app that uses some JavaScript to fetch data from an API endpoint.
In Safari and FireFox, I can request the page multiple times in a row and the data is fetched and displayed promptly. In Chrome, by contrast, the data is fetched and displayed promptly only if the dev tools are open or if my cache is clear (though I'm not disabling the cache in the dev tools).
If the dev tools are not open or Chrome has cached the page, reloading the page takes about 10 seconds to make the request and display the data.
Does anyone have any idea what might be causing this behavior? Full app source.
The API request in question used isomorphic-fetch to make the request. I replaced the isomorphic-fetch code with an old school AJAX request and now the requests are triggering immediately as expected.
Before:
import fetch from 'isomorphic-fetch';
export const fetchTreeData = () => {
return function(dispatch) {
return fetch(config.endpoint + 'tree')
.then(response => response.json()
.then(json => ({
status: response.status,
json
})))
.then(({ status, json }) => {
if (status >= 400) dispatch(treeRequestFailed())
else dispatch(receiveTreeData(json))
}, err => { dispatch(treeRequestFailed(err)) })
}
}
After:
export const fetchTreeData = () => {
return function(dispatch) {
get(config.endpoint + 'tree',
(data) => dispatch(receiveTreeData(JSON.parse(data))),
(e) => console.log(e))
}
}
const get = (url, success, err, progress) => {
const xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = () => {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status === 200) {
if (success) success(xmlhttp.responseText);
} else {
if (err) err(xmlhttp);
}
};
};
xmlhttp.onprogress = (e) => {if (progress) progress(e)};
xmlhttp.open('GET', url, true);
xmlhttp.send();
};

XMLHttpRequest is working with IE11 only when fiddler is running

I am new angular 2.
Currently I am working on application which has Padarn server at backend and HTML5 with Angular2 at front end.
I wanted ship one password protected zip file to backend, to achieve this I have written following code but that is not working with IE 11 (works properly when fiddler is running) . Same code is working with Chrome and Firefox browsers.
private makeFileRequest(url: string, params: Array, files: File) {
return new Promise((resolve, reject) => {
var formData: FormData = new FormData();
formData.append("uploads", files, files.name);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
resolve(xhr.response);
} else {
reject(xhr.response);
}
}
}
xhr.open("PUT", url, true, ApplicationObjects.configuration.Username, ApplicationObjects.configuration.Password);
xhr.send(formData);
});
Please help.

Not able to download OBJ file using GetDerivativeManifest

I am trying to download an OBJ file generated from SVF file, using the Autodesk.Forge .NET API method GetDerivativeManifest (C#). The OBJ file has been created successfully. However, the method does not provide a Stream that I can use to retrieve the file and save it locally.
How can I get the OBJ file?
I don't have a C# sample ready to give you, but I hit the same issue with the Node.js SDK. I worked around by implementing the REST call myself:
download (token, urn, derivativeURN, opts = {}) {
// TODO SDK KO
//this._APIAuth.accessToken = token
//
//return this._derivativesAPI.getDerivativeManifest(
// urn,
// derivativeURN,
// opts)
return new Promise((resolve, reject) => {
const url =
`${DerivativeSvc.SERVICE_BASE_URL}/designdata/` +
`${encodeURIComponent(urn)}/manifest/` +
`${encodeURIComponent(derivativeURN)}`
request({
url: url,
method: 'GET',
headers: {
'Authorization': 'Bearer ' + token.access_token
},
encoding: null
}, function(err, response, body) {
try {
if (err) {
return reject(err)
}
if (response && [200, 201, 202].indexOf(
response.statusCode) < 0) {
return reject(response.statusMessage)
}
if (opts.base64) {
resolve(bufferToBase64(body))
} else {
resolve(body)
}
} catch(ex) {
console.log(ex)
reject(ex)
}
})
})
}
Here is how I invoke that method within my endpoint:
/////////////////////////////////////////////////////////
// GET /download
// Download derivative resource
//
/////////////////////////////////////////////////////////
router.get('/download', async (req, res) => {
try {
const filename = req.query.filename || 'download'
const derivativeUrn = req.query.derivativeUrn
// return base64 encoded for thumbnails
const base64 = req.query.base64
const urn = req.query.urn
const forgeSvc = ServiceManager.getService(
'ForgeSvc')
const token = await forgeSvc.get2LeggedToken()
const derivativesSvc = ServiceManager.getService(
'DerivativesSvc')
const response = await derivativesSvc.download(
token, urn, derivativeUrn, {
base64: base64
})
res.set('Content-Type', 'application/octet-stream')
res.set('Content-Disposition',
`attachment filename="${filename}"`)
res.end(response)
} catch (ex) {
res.status(ex.statusCode || 500)
res.json(ex)
}
})
Hope that helps