FineUploader Failing to parse incoming JSON - json

I'm using play/scala for a webapp and a scala API, currently running simply on two different ports on localhost:9000 and localhost:8080 respectively. I have the basic page from the fine-uploader.com website docs, and a simple test page build in Play. (FWIW, i don't think much of the above is relevant)
When i post a file, chunked or not, Fine uploader receives a 200 from the API and valid JSON, but JSON.parse returns a failure. The logging from fine-uploader is below. If i take this output and run it through (in the console)
JSON.parse(JSON.stringify(json))
a valid object is returned. I can't just JSON.parse(json) directly in the browser tools b/c its already an object. I have checked the types by console.log'ing typeOf json in the qq.parseJson method and it returns string, so no conversion should be required, though i have tried it with the same results.
fine-uploader console logs:
[Fine Uploader 5.5.1] Sending simple upload request for 0 fine-uploader.js:251
[Fine Uploader 5.5.1] xhr - server response received for 0 fine-uploader.js:251
[Fine Uploader 5.5.1] responseText = {"code":"UPLOAD_COMPLETE","response":{"MediaModel":{"id":1103,"publicUri":"http://localhost:8080/media/Archive.zip","fileLocation":"/src/services/api/src/main/webapp/media/Archive.zip","mediaDate":{"year":2016,"month":2,"day":28},"mediaOrder":1,"viewName":"","caption":"","altText":"","isPublic":1,"fileSize":1107080,"created":"2016-02-28T14:58:43Z"},"UserMediaModel":{"id":1,"userId":24,"mediaId":3,"created":"2016-02-17T12:48:18Z"}},"errors":[]} fine-uploader.js:251
[Fine Uploader 5.5.1] Received response status 200 with body: {"code":"UPLOAD_COMPLETE","response":{"MediaModel":{"id":1103,"publicUri":"http://localhost:8080/media/Archive.zip","fileLocation":"/src/services/api/src/main/webapp/media/Archive.zip","mediaDate":{"year":2016,"month":2,"day":28},"mediaOrder":1,"viewName":"","caption":"","altText":"","isPublic":1,"fileSize":1107080,"created":"2016-02-28T14:58:43Z"},"UserMediaModel":{"id":1,"userId":24,"mediaId":3,"created":"2016-02-17T12:48:18Z"}},"errors":[]} fine-uploader.js:251
[Fine Uploader 5.5.1] Simple upload request failed for 0
The server is responding with a 200 per the API logs and i can see the exact response object in the Response tab of Chrome Dev tools.
I added a custom error handler, but not more more information was provided, just that the error is the text output
Error on file number 0 - Archive.zip. Reason: {"code":"UPLOAD_COMPLETE",....same as above
Lastly, all rows are propery inserted into the database as you see from the id's created above. And all logging points to an equally successful action.
Thanks for any pointers. I've also put this output in http://jsonlint.com/ and it parses fine.
Thanks! (sorry for the lack of JSON formatting, i can change it, but this seemed long enough already)
EDIT
It seems that i have satisfied the requirements stated in the other question with "success":true and Content-Type=text/plain. The following, per request is the JSON output and the headers
Headers:
Key: Access-Control-Allow-Origin Value: http://localhost:9000
Key: Date Value: Mon, 29 Feb 2016 00:55:19 GMT
Key: Access-Control-Allow-Credentials Value: true
Key: Content-Type Value: text/plain; charset=UTF-8
{
"code": "UPLOAD_COMPLETE",
"response": {
"MediaModel": {
"id": 1169,
"publicUri": "http://localhost:8080/media/Archive.zip",
"fileLocation": "/src/services/api/src/main/webapp/media/Archive.zip",
"mediaDate": {
"year": 2016,
"month": 2,
"day": 28
},
"mediaOrder": 1,
"viewName": "",
"caption": "",
"altText": "",
"isPublic": 1,
"fileSize": 1107080,
"created": "2016-02-29T00:55:19Z"
},
"UserMediaModel": {
"id": 1,
"userId": 24,
"mediaId": 3,
"created": "2016-02-17T12:48:18Z"
}
},
"errors": [],
"success": true
}
I'm sure this will end up being something silly, so i appreciate the input.

Based on the error reported by Fine Uploader, your response is not properly formatted. If you look closely at the response in your browser's network tab (such as with Chrome dev tools), you'll likely see a JSON string that, once parsed using JSON.parse results in another JSON string instead of a JavaScript object containing the expected properties. I can't confirm this as you haven't posted the exact response from your server, but I'm certain that this is the case. This is most likely caused by an encoding issue server-side. For example, your server should return this: {"foo": "bar", "success": true} instead of this: "{\"foo\": \"bar\", \"success\": true}". I suspect your server is returning the latter.

Related

Cypress intercept API JSON response and extract URL

My web app sends an API POST request to create an application and returns JSON response. I want to access one particular JSON object from that response.
My JSON starts like this
[
{
"status_code": 201,
"body": {
"created": "2021-01-28T00:00:00Z",
"modified": "2021-01-28T00:00:00Z",
"id": "a2d86d17-9b3c-4c4d-ac49-5b9d8f6d6f8f",
"applicant": {
"id": "07f1e1d3-0521-401b-813e-3f777f2673c6",
"status": "Pending",
"first_name": "",
"last_name": "",
"URL": "some onboarding url"
And I wanna take that URL in the JSON response and visit it later in my cypress automation script.
Notice that the JSON repsonse starts with a square bracket not a curly bracket, which means, the whole response is an object, I assume?
My cypress script looks like this
cy.contains('button', 'CONTINUE').click()
cy.EmailGen('candidate').then(email => {
cy.get('#emails\\[0\\]').type(`${email}`)
cy.wrap(email).as('candidateEmail')
})
//writing intercept here, before the Send application button, which triggers the POST req.
cy.intercept('/hr/v1/applications/invite').as('getURL')
cy.get('button').contains('SEND APPLICATION').click({ force: true })
//waiting on the alias of intercept and using interception to print objects from response
cy.wait('#getURL').then((interception)=> {
cy.log(interception.response.body.applicant.URL)
})
cy.Logout()
The script executes with no errors. Just that nothing is logged in the cy.log statement. Below is the screen.
I also tried using another method as given below.
cy.intercept('/hr/v1/applications/invite',(req) => {
req.reply((res=> {
expect(res.status_code).to.equal('201')
expect(res.body.applicant.status).to.equal('Pending')
}))
})
In this case, I get a assert error embedded with the request and response along with some other stuff which I am unable to understand.
The complete error goes something like this...
"expected The following error originated from your test code, not from Cypress.\n\n > A response callback passed to req.reply() threw an error while intercepting a response:\n\nexpected undefined to equal '201'\n\nRoute: {\n "matchUrlAgainstPath": true,\n "url": "/hr/v1/applications/invite"\n}\n\nIntercepted request:{} Intercepted response: {} When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. to include window.zE is not a function"
Its a bit weird to read this..
My application sometimes throws this exception, which I have handled using following code.
cy.on('uncaught:exception', (err, runnable) => {
expect(err.message).to.include('window.zE is not a function')
done()
return false
})
I really hope I have explained everything here. Please, help a noob.
Regards
As Richard Matsen suggested in the comments,
I used console.log(interception.response) and checked the console output in the browser controlled by Cypress.
I Noticed that the response json structure was something different than what I got in the network tab of developers tools, while using the web app.
The response was something like below...
{headers: {…}, url: "https://example.com/hr/v1/applications/invite/batch/", method: null, httpVersion: "1.1", statusCode: 200, …}
body: Array(1)
0:
body:
applicant: {id: "c6b2d686-d4f3-483e-abc8-e4641c365845", status: "Pending", first_name: "", last_name: "", email: "qa2+candidate879#example.com", …}
applicant_status: "NONE"
applicant_status_label: "None"
created: "2021-01-29T00:00:00Z"
get_applicant_status_display: "None"
id: "ad2939f5-c8ab-490a-a9e1-b0474de69e2c"
URL: "some url"
This made me modify the json traverse to
interception.response.body[0].body.applicant.URL
If others have a neat way to handle this, please let me know!

extract json with nodered

I want to extract json part in a message with node red
I receive the message in node red but I can't extract the data
exemple of a message:
POST / HTTP/1.1
Host: xxx.xx.xxx.5:9000
User-Agent: libcurl-agent/1.0
Content-type: application/json
Accept: application/json
Content-Length: 526
{
"timestamp": 1571997083,
"data": {
"temperature": 20.613545532227,
"humidity": 61.3828125,
"battery": 3.47
},
"frame": "814962xxxx16a1dc5",
"gatewayID": "AA555Axxxx0xx964",
"othersGW": [],
"clientID": "xxxx",
"DevAddr": "011xxxxb",
"DevEUI": "8cf9xxx000000xxx",
"sensorInstallId": "8cf95xxx0000xxxx",
"loraPort": 8,
"fcnt": 1607,
"rxpk": {
"tmst": 2380181019,
"time": "2019-10-25T09:51:23.472998Z",
"chan": 0,
"rfch": 0,
"freq": 867.1,
"stat": 1,
"modu": "LORA",
"datr": "SF7BW125",
"codr": "4/5",
"lsnr": 9,
"rssi": -72,
"size": 22,
"data": "xxxxxxxxxxxxxxxx/YxWg=="
}
}
so I would like to have data of temperature etc...
and I don't know the node I have to use
Thanks a lot
Having got a better view of what you are trying to do from the comments.
Using the TCP-in node is probably not the right approach for this. You will do much better using the HTTP-in/HTTP-out nodes as these will handle dealing with all the HTTP-header and sending a proper response to the client so the connection gets closed.
The HTTP-in node takes a path e.g. /input which will be appended to the Node-RED URL giving something like http://localhost:1880/input. It also takes a HTTP verb which in this case would be POST. You can find more details and lots of examples in the Node-RED cookbook here.
You will need to update the client to point to the correct path and port.
You will need JSON node to convert the message string into an object.
Nodered has a very good documentation and hands on examples.
See below for some help:
This is great example how to to use the json node
This
describes how to work with JSON data

AWS API Gateway Mapping Template JSON

I've got a API stage that's NOT using "Lambda Proxy integration" which has a Lambda function passing an error.
In the mapping template I have this:
$input.path("$.errorMessage")
Which results in the output of this:
{
"headers": {
"apiVersion": "20190218.1",
"isTesting": true
},
"body": {
"statusCode": 503,
"status": "Service Unavailable",
"title": "One or more of our data providers are currently offline for scheduled maintenance"
}
}
The header values are mapped to template headers and pull through correctly, however I need the body to transform to this:
{
"statusCode": 503,
"status": "Service Unavailable",
"title": "One or more of our data providers are currently offline for scheduled maintenance"
}
Whatever I have tried, body always returns as a blank string, an empty body, or an invalid JSON.
This is the closest I've got but it returns an invalid JSON:
$util.parseJson($input.path("$.errorMessage")).body
Result (comes back with no quotes):
{statusCode=503, status=Service Unavailable, title=One or more of our data providers are currently offline for scheduled maintenance}
Is it possible to do what I'm after? I can't find a reverse for $util.parseJson (i.e, stringify).
Thanks!
I think the original poster has probably moved on in the past 11 months, but in case anyone else stumbles across this question, $input.json('$.errorMessage.body') should work.

Chrome Web notification 'MismatchSenderId' error

I have deployed the sample code for Chrome push notifications and updated the gcm_sender_id to a newly configured project, the client is able to subscribe/unsubscribe without issue but when posting a request to send a notification the response MismatchSenderId is continually returned.
I have tried creating multiple new projects console.firebase.google.com, but nothing seems to work.
Request:
POST /gcm/send HTTP/1.1
Host: android.googleapis.com
Authorization: key=<Server Key/>
Content-Type: application/json
{
"registration_ids":[
"<Registration-ID/>"
]
}
Response:
{
"multicast_id": 6881038306061588882,
"success": 0,
"failure": 1,
"canonical_ids": 0,
"results": [
{
"error": "MismatchSenderId"
}
]
}
I am using the 'Server Key' as the request auth token (which works as 401 is returned when an invalid key is used) and am using the 'Sender ID' in the manifest:
manifest.json
{
"name": "Notification Demo",
"gcm_sender_id": "<Sender ID/>"
}
This was my own fault; the sample registration ID's were in a different format to the generated ones I was seeing and did not contain semicolons which I was using to strip the registration ID from the subscription endpoint string. Splitting the endpoint by a forward slash and taking the last instance returned the correct Registration ID which works fine.

What are the differences between application/json and application/x-www-form-urlencoded?

What is the difference between
request.ContentType = "application/json; charset=utf-8";
and
webRequest.ContentType = "application/x-www-form-urlencoded";
The first case is telling the web server that you are posting JSON data as in:
{"Name": "John Smith", "Age": 23}
The second case is telling the web server that you will be encoding the parameters in the URL:
Name=John+Smith&Age=23
webRequest.ContentType = "application/x-www-form-urlencoded";
Where does application/x-www-form-urlencoded's name come from?
If you send HTTP GET request, you can use query parameters as follows:
http://example.com/path/to/page?name=ferret&color=purple
The content of the fields is encoded as a query string. The application/x-www-form-
urlencoded's name come from the previous url query parameter but the query parameters is
in where the body of request instead of url.
The whole form data is sent as a long query string.The query string contains name-
value pairs separated by & character
e.g. field1=value1&field2=value2
It can be simple request called simple - don't trigger a preflight check
Simple request must have some properties. You can look here for more info. One of
them is that there are only three values allowed for Content-Type header for simple
requests
application/x-www-form-urlencoded
multipart/form-data
text/plain
3.For mostly flat param trees, application/x-www-form-urlencoded is tried and tested.
request.ContentType = "application/json; charset=utf-8";
The data will be json format.
axios and superagent, two of the more popular npm HTTP libraries, work with JSON bodies by default.
{
"id": 1,
"name": "Foo",
"price": 123,
"tags": [
"Bar",
"Eek"
],
"stock": {
"warehouse": 300,
"retail": 20
}
}
"application/json" Content-Type is one of the Preflighted requests.
Now, if the request isn't simple request, the browser automatically sends a HTTP request before the original one by OPTIONS method to check whether it is safe to send the original request. If itis ok, Then send actual request. You can look here for more info.
application/json is beginner-friendly. URL encoded arrays can be a nightmare!
One of the biggest differences between the two is that JSON-encoding the post usually preserves the data types of the values that are sent in (as long as they are valid JSON datatypes), whereas application/x-www-form-urlencoded will usually have all properties converted to strings.
For example, in the JSON-encoded post of:
{"Name": "John Smith", "Age": 23}
the server will most likely parse the Age property as the integer 23.
Whereas in
Name=John+Smith&Age=23
the server will most likely parse Age as the string "23".
Of course, if you are using other layers to parse these values and convert them to the appropriate types, this may not be an issue.