I have used the multiple-file upload script from valums.com/ajax-upload/
How I can handle the JSON-response?
The actually input parameter 'responseJSON' of the onComplete function is some __proto__: Object object. It hasn't the valid JSON format.
However, the server response has the valid JSON format content. Below you may see onComplete function and debugger screenshot link.
Debugger screenshot - http://bit.ly/sB5mK0
Uncaught ТуреЕrrоr: Cannot read property 'src' of null
onComplete : function(id, filename, responseJSON) {
console.log('File upload for file %s, id %s done with status %s',
filename, id, responseJSON);
var json = $.parseJSON(responseJSON);
avatarPreview.attr('src', json.src);
}
You may see the request and response content on the next link:
http://pastebin.com/aWcTaUAJ
Thank you very much for your time!
Related
I have some issue with using Fetch API JavaScript method when sending some simple formData like so:
function register() {
var formData = new FormData();
var textInputName = document.getElementById('textInputName');
var sexButtonActive = document.querySelector('#buttonsMW > .btn.active');
var imagesInput = document.getElementById('imagesInput');
formData.append('name', textInputName.value);
if (sexButtonActive != null){
formData.append('sex', sexButtonActive.html())
} else {
formData.append('sex', "");
}
formData.append('images', imagesInput.files[0]);
fetch('/user/register', {
method: 'POST',
data: formData,
})
.then(response => response.json());
}
document.querySelector("form").addEventListener("submit", register);
And on the server side (FastAPI):
#app.post("/user/register", status_code=201)
def register_user(name: str = Form(...), sex: str = Form(...), images: List[UploadFile] = Form(...)):
try:
print(name)
print(sex)
print(images)
return "OK"
except Exception as err:
print(err)
print(traceback.format_exc())
return "Error"
After clicking on the submit button I get Error 422: Unprocessable entity. So, if I'm trying to add header Content-Type: multipart/form-data, it also doesn't help cause I get another Error 400: Bad Request. I want to understand what I am doing wrong, and how to process formData without such errors?
The 422 response body will contain an error message about which field(s) is missing or doesn’t match the expected format. Since you haven't provided that (please do so), my guess is that the error is triggered due to how you defined the images parameter in your endpoint. Since images is expected to be a List of File(s), you should instead define it using the File type instead of Form. For example:
images: List[UploadFile] = File(...)
^^^^
When using UploadFile, you don't have to use File() in the default value of the parameter. Hence, the below should also work:
images: List[UploadFile]
Additionally, in the frontend, make sure to use the body (not data) parameter in the fetch() function to pass the FormData object (see example in MDN Web Docs). For instance:
fetch('/user/register', {
method: 'POST',
body: formData,
})
.then(res => {...
Please have a look at this answer, as well as this answer, which provide working examples on how to upload multiple files and form data to a FastAPI backend, using Fetch API in the frontend.
As for manually specifying the Content-Type when sending multipart/form-data, you don't have to (and shouldn't) do that, but rather let the browser set the Content-Type—please take a look at this answer for more details.
So, I found that I has error in this part of code:
formData.append('images', imagesInput.files[0]);
Right way to upload multiple files is:
for (const image of imagesInput.files) {
formData.append('images', image);
}
Also, we should use File in FastAPI method arguments images: List[UploadFile] = File(...) (instead of Form) and change data to body in JS method. It's not an error, cause after method called, we get right type of data, for example:
Name: Bob
Sex: Man
Images: [<starlette.datastructures.UploadFile object at 0x7fe07abf04f0>]
I am doing "window.open(file_url)" to download a file and if a file exists backend returns a Blob which gets downloaded by the browser but if the file doesn't exist then backend returns a JSON error message with request status as 500.
so is there is some way to know that "status" for a page.
I know for AJAX we get the status property but for normal web pages do we have some way to know that status since when the browser makes a request for a page its an HTTP GET and it should have status.
This is a working example code. So, you should use it.
$.get(url, function(data,status, xhr) {
alert(xhr.status);
});
You can check for error as
var test = window.open(file_url)
test.onError = alert('The specified file was not found. Has it been renamed or
removed?');
I am trying to read ByteArray to show PDF form Java into Angular JS using
method : 'GET'
url : '',
cache : isCache||false,
responseType: 'arraybuffer'
This is working fine when everything okay.
But when I throw an exception with some proper JSON and marking HTTP Status as bad request, I can't read JSON response even after changing config to respone.config.responseType='application/json'.
It showing only empty ArrayBuffer {} on response.data.
But important thing here is, I can see JSON response in google chrome developer tool request.
I googled, searched on stack overflow but didn't find much.
Below lines added later
I am adding response object picture and data received pic from chrome network connection.
First Image : Response object from error function of angular JS.
Second Image - Server returning proper JSON message
Third Image - Request and Response Header pics
Only problem I am facing is not able read data of response as I set response type to arraybuffer
Instead of expecting arraybuffer why not expect application/json all the time, then when you return your data that's supposed to create your pdf, do a base64 of the data, put it in a json object and return it to the client
Even when you throw an exception you still expect JSON. Your response from server side could be something like:
{
responseCode: // your response code according to whether the request is success or not,
responseMessage: // success or fail
data: // your base64 encoded pdf data(the data that if the request is successful will be returned), note it will be returned as a normal string
} // I'm hoping you know how to base64 encode data
Then in your client side(Javascript), perform an if
if(data.responseCode == //errorCode) {
alert(data.responseMessage);
} else {
// Unpack data
var myPdfData = // base64 decode(data.data)
// Do logic to create and open/download file
}
You don't even need to decode the data, you just create a blob object, then trigger a download from the blob
If the responsetype is arraybuffer, to view it, you should convert it into a blob and create a objectUrl from that blob, and the download it or open in a new tab/browser window to view it.
Js:
$http.get('your/api/url').then(function(response) {
var blob = new Blob([response.data], { type: 'application/pdf' });
var downloadUrl = URL.createObjectURL(blob);
$timeout(function () {
var link = document.createElement('a');
link.download = 'SOME_FILE_NAME'+ '.pdf';
link.href = downloadUrl;
link.click();
}, 100);
}, function(errorResponse){
alert(errorResponse.error.message);
});
I have a PHP application running and I'm uploading a PDF for processing. I have not overridden any PHP ini values, so I'm expecting the post to be able to handle 32MB of data and a timeout of 60 seconds.
When I upload a large document (7.7MB in this case), the app fails in 2 very different ways.
The back end times out and returns successfully having apparently been passed duff data
The backend does not timeout (returning in under a minute) but has an internal server error
The timeout seems to manifest as the back end PHP page getting no data, i.e. whatever is doing the transport times out rather than my page timing out. I can handle this scenario because of the duff data passed in and pass back a useful error message. I don't seem to be able to reproduce this on my local development machine.
The second issue is perplexing as it happens almost immediately on my dev machine and also if the page response is under 1 minute on GAE. I can upload a document of 4.1MB and all is good. The 7.7MB doc causes this every time. The headers look fine and the form data has all the data it needs, although I haven't tried to decode the form data.
Is there another PHP setting causing this? Is there a way to alter this? What could possibly be going on? Could this be a javascript thing as I am using javascript file reader in an HTML5 dropzone - here are the appropriate portions of the handler code:
function loadSpecdoc(file) {
var acceptedTypes = {
'application/pdf' : true
};
if (acceptedTypes[file.type] === true) {
var reader = new FileReader();
reader.onload = function(event) {
$.ajax({
url : "my_handler.php",
type : 'POST',
dataType : "json",
data : {
spec_id : $('#list_spec_items_spec_id').val(),
file_content : event.target.result
},
success : function(response) {
// Handle Success
},
error : function(XMLHttpRequest, textStatus, exception) {
// Handle Failure
},
async : true
});
};
reader.readAsDataURL(file);
} else {
alert("Unsupported file");
console.log(file);
}
};
I have heard of the Blob store but I'm on a bit of a deadline and can't find an documentation on how to make it work in javascript, and can't get the file to my PHP application to use it.
Any help much appreciated.
EDIT: I have just checked in the chrome javascript network console and there are 2 sizes in the "Size Content" column, 79B and 0B, I'm guessing that this is the size up (79B) and response (0B). This being the case, this seems to be a javascript issue??
EDIT 2: Just found the log for my application and it says there is a post content limit of about 8MB... not quite the 32MB I was expecting:
06:26:03.476 PHP Warning: Unknown: POST Content-Length of 10612153 bytes exceeds the limit of 8388608 bytes in Unknown on line 0
EDIT 3: Just found this on limits:
https://cloud.google.com/appengine/docs/php/requests#PHP_Quotas_and_limits
I am expecting 32MB of post, assuming I can upload it quick enough :) How do I fix this?
I'm setting up a vert.x project in which I'm sending a snippet of JSON from my Java based server to a javascript client via websocket.
Vert.x server sending the JSON:
vertx.eventBus().send("mongodb-persistor", collectionsQuery, new Handler<Message<JsonObject>>() {
#Override
public void handle(Message<JsonObject> data) {
container.logger().info(data.body().encodePrettily());
ws.write(new Buffer(data.body().toString()));
}
});
The data being sent as outputted on the console:
{
"collections" : [ "AAPL", "AZN", "GOOG", "YHOO", "system.indexes" ],
"status" : "ok"
}
When i receive this on the client:
socket.onmessage = function(event) {
alert("Received data from websocket: " + event.data);
var x = JSON.parse(event.data);
};
I'm getting the error:
Uncaught SyntaxError: Unexpected token o (index):124socket.onmessage
I've read up and it appears as though that's because the JSON has already been parsed. So if I don't parse the JSON, how do i actually access my data? If i just output event.data as string, all I get is the type and size as opposed to the data logged on the console.
EDIT:
I also get the error "Failed to load resource: the server responded with status 404" off the following line /sometimes/, even though event.data is still populated with the correct message size.
alert("Received data from websocket: " + event.data);
Any help is appreciated and I hope this information is self contained enough!
Thanks :)
Turns out in vert.x I shouldn't be returning the JSON wrapped in a Buffer.
Instead I used the method writeTextFrame
vertx.eventBus().send("mongodb-persistor", collectionsQuery, new Handler<Message<JsonObject>>() {
#Override
public void handle(Message<JsonObject> data) {
container.logger().info(data.body().toString());
ws.writeTextFrame(data.body().encode());
}
});