In Go, you can read a form sent using Ajax and FormData using r.ParseMultipartForm(), which populates the Form map with form request data.
func form(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(500) //
fmt.Fprintf(w, "This is the value of %+v", r.Form)
}
However, I haven't found a method to parse Blobs. The above code returns an empty map whenever instead of sending a form, I send a Blob. That is, when I send this:
var blob = new Blob([JSON.stringify(someJavascriptObj)]);
//XHR initialization, etc. etc.
xhr.send(blob);
the Go code above doesn't work. Now, when I send this:
var form = new FormData(document.querySelector("form"));
//...
xhr.send(form);
I can read form data without problems.
r.ParseMultipartForm(500)
Perhaps an error is being returned here? Try capturing the error:
if err := r.ParseMultipartForm(500); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
Also, consider raising the 500 byte memory limit as larger blobs will be written to temporary files.
I think javascript treats blob as file, so your can look it in r.MultipartForm.File, get file header, open it, read, decode and parse.
Try for example
r.ParseMultipartForm(500)
fmt.Fprintf(w, "This is the value of %+v", *r.MultipartForm.File)
}
I presume Javascript's Blob is a hex string which can eventually be converted to []byte, which is a standard type for JSON in Go.
// Once you get the blob
blobString := `7b22666f6f223a205b22626172222c202262617a222c2039395d7d`
b, _ := hex.DecodeString(blobString)
json := string(b)
fmt.Println(json) // prints out {"foo": ["bar", "baz", 99]}
You might want to look into encoding/hex and encoding/binary packages to decode your blob acquired from Javascript to type []byte in Go, if it's not already.
Related
I cannot send data of <textarea> to node js, Node js don't see the my sent data.
For Fetch data to Node Js
continueBtn.addEventListener("click", async () => {
console.log(myMsg.value)
console.log(typeof(myMsg.value))
const req = await fetch("/sendmsg", {method: "POST",body: myMsg.value}) ;
console.log("Fetched")
})
For get data in Node js
const {userMessage} = Object.keys(req.body)
You are passing a string to body. Since you aren't overriding it, it will be given a text/plain content-type.
On the server you expect req.body to contain an object.
You haven't shown us what, if any, body parsing middlewares you have configured in your server side code, but none of the common ones will convert something that is text/plain into an object.
You should:
Make sure that you have a body parsing middleware configured
Encode the data you are passing to body (e.g. with URLSearchParams) so it has name=value pairs instead of being a plain string.
If you end up passing a string (e.g. if you pass a string of JSON instead of a URLSearchParams object) then you'll also need to set a Content-Type request header that matches your data format.
"const {userMessage} = Object.keys(req.body)"
I don't see why you'd be expecting to have a userMessage key in your body object with the code you pasted. It's possible the data is being passed properly, but you are trying to access the wrong key. I would try logging in your server code to debug the response format as a first step:
console.log(JSON.stringify(req.body))
Let me know if that gets you enough help to move forward, and I can circle back here if not.
I am calling a REST API in my project for creating some records.
Everything is working fine but I got a challenge, the JSON request body is too big (having thousands of keys and values).
Now I want to compress the request body. I tried it using JavaScript
var reqJSON = { ... } // too big JSON object
var compressedJSON = JSON.stringify(reqJSON, null, 0); // converting JSON to String (compression)
Now I am sending the string in the request body and converting this string into JSON at the server-side.
I am curious, is it the correct way of JSON compression? If yes how can I check the difference in the request body size?
Thanks for your time.
That isn't compression at all.
var reqJSON = { ... } // too big JSON object
That will give you a JavaScript object, not JSON. Possibly your Ajax library will convert it to JSON if you pass it. There's no way for us to know. If the data is to get to the server then it will need serializing to some format that can be sent over the wire so something must be converting it before the HTTP request is made.
var compressedJSON = JSON.stringify(reqJSON, null, 0); // converting JSON to String (compression)
That will give you JSON. There's no compression involved though.
If you want to compress it then you'd need to look for a library that can do actual compression.
You can use gzip for compress json its working fine
I'm sending an ack to a received message in Node.js server and I want to echo the messageId back to the client. Currently I'm parsing the messageId from a buffer to string and building the ack from the string. Parsing the id to string and back is unnecessary but I'm unable to build the ack directly with the stuct buffer.
This is how it works when messageid is passed in as a string.
function createAck(messageId) {
let builder = new flatbuffers.Builder;
const request = MyServer.MessageAck;
request.startMessageAck(builder);
request.addMessgeId(builder, createUUID(builder, messageId));
const requestMessage = request.endMessageAck(builder);
return builder.finish(requestMessage);
}
function createUUID(builder, messageId) {
let uuidBytes = new Uint8Array(uuidParse.parse(messageId));
let dataview = new DataView(uuidBytes.buffer);
return MyServer.UUID.createUUID(builder,
flatbuffers.Long.create(dataview.getInt32(0, true), dataview.getInt32(4, true)),
flatbuffers.Long.create(dataview.getInt32(8, true), dataview.getInt32(12, true)));
}
I would like to pass in the messageId as a buffer directly taken from the message with
request.addMessgeId(builder, messageId);
But I'm getting an error: 'FlatBuffers: struct must be serialized inline.'
Here is the struct:
struct UUID {
low_bytes: ulong;
high_bytes: ulong;
}
The error refers to the fact that structs must be stored in-line, i.e. their bytes must be written to the buffer in between startMessageAck and endMessageAck. You can't refer to a struct stored elsewhere.
You should be able to copy the existing struct without using the intermediate Uint8Array and DataView however, something along the lines of (not tested):
request.addMessgeId(builder, MyServer.UUID.createUUID(builder,
messageId.low_bytes(), messageId.high_bytes());
Assuming messageId is a reference to an incoming UUID struct, can't tell from your code.
Even better would be if you could copy the struct using the JS equivalent of C memcpy, but that would require some hackery directly on the ByteBuffer in the builder that the current API doesn't directly support, so is probably not worth it for just 2 fields.
For example, I have a .JSON file that has the following:
[{"honda": "accord", "color": "red"},{"ford": "focus", "color": "black"}]
What would be the javascript code to push another object {"nissan": "sentra", "color": "green"} into this .json array to make the .json file look like
[{"honda": "accord", "color": "red"},{"ford": "focus", "color": "black"},{"nissan": "sentra", "color": "green"}]
The reason I'm asking is I am finding a lot of information online on how to pull data from a .json file using AJAX but not writing new data to the .json file using AJAX to update the .json file with additional data.
Any help would be appreciated!
You have to be clear on what you mean by "JSON".
Some people use the term JSON incorrectly to refer to a plain old JavaScript object, such as [{a: 1}]. This one happens to be an array. If you want to add a new element to the array, just push it, as in
var arr = [{a: 1}];
arr.push({b: 2});
< [{a: 1}, {b: 2}]
The word JSON may also be used to refer to a string which is encoded in JSON format:
var json = '[{"a": 1}]';
Note the (single) quotation marks indicating that this is a string. If you have such a string that you obtained from somewhere, you need to first parse it into a JavaScript object, using JSON.parse:
var obj = JSON.parse(json);
Now you can manipulate the object any way you want, including push as shown above. If you then want to put it back into a JSON string, then you use JSON.stringify:
var new_json = JSON.stringify(obj.push({b: 2}));
'[{"a": 1}, {"b": 1}]'
JSON is also used as a common way to format data for transmission of data to and from a server, where it can be saved (persisted). This is where ajax comes in. Ajax is used both to obtain data, often in JSON format, from a server, and/or to send data in JSON format up to to the server. If you received a response from an ajax request which is JSON format, you may need to JSON.parse it as described above. Then you can manipulate the object, put it back into JSON format with JSON.stringify, and use another ajax call to send the data to the server for storage or other manipulation.
You use the term "JSON file". Normally, the word "file" is used to refer to a physical file on some device (not a string you are dealing with in your code, or a JavaScript object). The browser has no access to physical files on your machine. It cannot read or write them. Actually, the browser does not even really have the notion of a "file". Thus, you cannot just read or write some JSON file on your local machine. If you are sending JSON to and from a server, then of course, the server might be storing the JSON as a file, but more likely the server would be constructing the JSON based on some ajax request, based on data it retrieves from a database, or decoding the JSON in some ajax request, and then storing the relevant data back into its database.
Do you really have a "JSON file", and if so, where does it exist and where did you get it from? Do you have a JSON-format string, that you need to parse, mainpulate, and turn back into a new JSON-format string? Do you need to get JSON from the server, and modify it and then send it back to the server? Or is your "JSON file" actually just a JavaScript object, that you simply need to manipulate with normal JavaScript logic?
JSON can be written into local storage using the JSON.stringify to serialize a JS object. You cannot write to a JSON file using only JS. Only cookies or local storage
var obj = {"nissan": "sentra", "color": "green"};
localStorage.setItem('myStorage', JSON.stringify(obj));
And to retrieve the object later
var obj = JSON.parse(localStorage.getItem('myStorage'));
Unfortunatelly, today (September 2018) you can not find cross-browser solution for client side file writing.
For example: in some browser like a Chrome we have today this possibility and we can write with FileSystemFileEntry.createWriter() with client side call, but according to the docu:
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.
For IE (but not MS Edge) we could use ActiveX too, but this is only for this client.
If you want update your JSON file cross-browser you have to use server and client side together.
The client side script
On client side you can make a request to the server and then you have to read the response from server. Or you could read a file with FileReader too. For the cross-browser writing to the file you have to have some server (see below on server part).
var xhr = new XMLHttpRequest(),
jsonArr,
method = "GET",
jsonRequestURL = "SOME_PATH/jsonFile/";
xhr.open(method, jsonRequestURL, true);
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
// we convert your JSON into JavaScript object
jsonArr = JSON.parse(xhr.responseText);
// we add new value:
jsonArr.push({"nissan": "sentra", "color": "green"});
// we send with new request the updated JSON file to the server:
xhr.open("POST", jsonRequestURL, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// if you want to handle the POST response write (in this case you do not need it):
// xhr.onreadystatechange = function(){ /* handle POST response */ };
xhr.send("jsonTxt="+JSON.stringify(jsonArr));
// but on this place you have to have a server for write updated JSON to the file
}
};
xhr.send(null);
Server side scripts
You can use a lot of different servers, but I would like to write about PHP and Node.js servers.
By using searching machine you could find "free PHP Web Hosting*" or "free Node.js Web Hosting". For PHP server I would recommend 000webhost.com and for Node.js I would recommend to see and to read this list.
PHP server side script solution
The PHP script for reading and writing from JSON file:
<?php
// This PHP script must be in "SOME_PATH/jsonFile/index.php"
$file = 'jsonFile.txt';
if($_SERVER['REQUEST_METHOD'] === 'POST')
// or if(!empty($_POST))
{
file_put_contents($file, $_POST["jsonTxt"]);
//may be some error handeling if you want
}
else if($_SERVER['REQUEST_METHOD'] === 'GET')
// or else if(!empty($_GET))
{
echo file_get_contents($file);
//may be some error handeling if you want
}
?>
Node.js server side script solution
I think that Node.js is a little bit complex for beginner. This is not normal JavaScript like in browser. Before you start with Node.js I would recommend to read one from two books:
Learning Node: Moving to the Server-Side
Node.js Web Development: Server-side development
The Node.js script for reading and writing from JSON file:
var http = require("http"),
fs = require("fs"),
port = 8080,
pathToJSONFile = '/SOME_PATH/jsonFile.txt';
http.createServer(function(request, response)
{
if(request.method == 'GET')
{
response.writeHead(200, {"Content-Type": "application/json"});
response.write(fs.readFile(pathToJSONFile, 'utf8'));
response.end();
}
else if(request.method == 'POST')
{
var body = [];
request.on('data', function(chunk)
{
body.push(chunk);
});
request.on('end', function()
{
body = Buffer.concat(body).toString();
var myJSONdata = body.split("=")[1];
fs.writeFileSync(pathToJSONFile, myJSONdata); //default: 'utf8'
});
}
}).listen(port);
Related links for Node.js:
How to Develop Web Application using pure Node.js (HTTP GET and POST, HTTP Server) (detailed video tutorial)
Anatomy of an HTTP Transaction
How to handle POST request in Node.js
How do you extract POST data in Node.js?
In my back-end golang web server I have converted and processed a directory of images that i have read in using os.ReadDir
These images are stored as a [][]byte. I want to be able to send these images through a GET request to be displayed in the browser using Javascript.
I am having trouble figuring out how to begin the process to send the data from the Golang web server. The resources I am currently using are the typical net/http package, and Gorilla Mux/Websockets.
Here is some sample code that shows how I am currently doing a get request which return some json. How can I similarly send a [][]byte array instead of rendering a template or JSON?
import (
"html/template"
"log"
"net/http"
"encoding/json"
"github.com/gorilla/mux"
)
func ViewSample(rw http.ResponseWriter, req *http.Request) {
type Sample struct {
Id int `json:"id"`
Name string `json:"name"`
User string `json:"user
}
params := mux.Vars(req)
sampleId := params["id"]
sample := Sample{
Id: 3,
Name: "test",
User: "testuser"
}
json.NewEncoder(rw).Encode(sample)
}
If your image is stored in a []byte, you can write that directly to the http.ResponseWriter
func GetImage(w http.ResponseWriter, r *http.Request) {
image, err := getImage() // getImage example returns ([]byte, error)
if err != {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write(image)
}
There's no way to send multiple images in a single response which is natively understood by clients. One method you could use is to return a json document on the first call, which contains a list of links to fetch each image individually.