How to get the data from http request in a standard way in golang? - ajax

I am trying to get the data from http request in golang. I am using net/http package. In my server handler I am trying to get the data from r.Body
body, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Printf("FATAL IO reader issue %s ", err.Error())
}
it works fine when I curl the service with some input data.
curl --data '{"AppName":"Proline","Properties":null,"Object":"","Timestamp":"2016:03:27 00:08:11"}' -XGET http://localhost:8081/api/services/test/
But when I try to call this service from ajax call r.Body is empty.
requestJSON = '{"AppName":"Proline","Properties":null,"Object":"","Timestamp":"2016:03:27 00:08:11"}'
$.ajax({
type: "GET",
url: "http://localhost:8081/api/services/test/",
data: requestJSON,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){alert(data);},
failure: function(errMsg) {
alert(errMsg);
}
});
So I changed to read the input data from r.Form
r.ParseForm()
var body []byte
for key, _ := range r.Form {
body = []byte(key)
break
}
But now the curl request fails. Is there a standard way to retrieve input data from http request in golang? I am using Go 1.6. Could someone help me with this?

Sending a meaningful body with a GET request is disallowed by the spec. So your browser is probably sending an empty body. You can use POST instead. Its unsurprising that r.ParseForm() is not working because it expects the body to be encoded by application/x-www-form-urlencoded. Not json.
If GET is more appropriate to send the user inputs to your server's request handlers you can use url query parameters.
Quoting JQuery.ajax() docs for data parameter,
Data to be sent to the server. It is converted to a query string, if
not already a string. It's appended to the url for GET-requests. See
processData option to prevent this automatic processing. Object must
be Key/Value pairs.
So you can do,
$.ajax({
type: "GET",
url: "http://localhost:8081/api/services/test/",
data: {AppName: "Proline", Properties:null, Object: ""}, // An object, not a string.
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){alert(data)}
})
An in the server,
params := r.URL.Query()
params.Get('AppName') // returns 'Proline'
See docs: https://golang.org/pkg/net/url/#URL.Query

Related

Forwarding POST request data in Golang

I have an AJAX post request that will hit the Golang backend. The goal is to edit this request before sending the request to an outside api endpoint.
The ajax POST request example:
var ajaxParams = {
type: 'POST',
url: '/golang_endpoint', // golang backend endpoint
dataType: 'json',
data: encodeURIComponent(JSON.stringify(request)), // this is the form we want to send to an external endpoint
success: onResponse,
error: onError,
};
$.ajax(ajaxParams);
This request will hit the associated Golang handler, and we want to edit some of the request before sending it out. However, we are getting errors just sending the request without any edits:
func golangEndpointHandler(rw http.ResponseWriter, req *http.Request) {
fmt.Println(req.PostForm)
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)
}
Specifically, we are getting 500 Internal Server Errors sending the POST request (ex: unexpected token at '='). Is using req.PostForm the right way to forward our request data? The error indicates maybe something with decoding/encoding req.PostForm or the data from the AJAX data param?
The print statement suggests a json serialization was performed:
map[{"size":"1000","other_data":12345}:[]]
EDIT: per #belindamichaels response.
I believe ParseForm does some sort of encoding/decoding that causes 500 responses once sent to the outside endpoint.
While this combination works:
var ajaxParams = {
type: 'POST',
url: '/golang_endpoint'
dataType: 'json',
processData: false,
timeout: timeout,
data: encodeURIComponent(JSON.stringify(request)),
success: onResponse,
error: onError,
};
resp, err := http.Post("webwsite.com/outside/endpoint", req.Header.Get("Content-Type"), req.Body)
This does not:
var ajaxParams = {
type: 'POST',
url: '/golang_endpoint'
dataType: 'json',
processData: false,
timeout: timeout,
data: request, // not stringified or url-encoded
success: onResponse,
error: onError,
};
req.ParseForm()
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)
Despite no editing of the request, we are getting 500's (specifically unexpected token at 'object Object]='). How can I stringify and urlencode the data once ready to send to the outside endpoint?
NOTE: the following combination also does not work:
var ajaxParams = {
type: 'POST',
url: '/golang_endpoint'
dataType: 'json',
processData: false,
timeout: timeout,
data: encodeURIComponent(JSON.stringify(request)), // the change
success: onResponse,
error: onError,
};
req.ParseForm()
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)
We get a similar 500 error: unexpected token at '='
To forward the request as is, use:
resp, err := http.Post("webwsite.com/outside/endpoint", req.Header.Get("Content-Type"), req.Body)
If you want to edit the request body, the server and client must agree on the type of the request body. Here's how to use application/x-www-form-urlencoded. Pass the form as is to the server. Don't encode the form as JSON as in the question.
var ajaxParams = {
type: 'POST',
url: '/golang_endpoint', // golang backend endpoint
dataType: 'json',
data: request,
success: onResponse,
error: onError,
};
Parse the form on the server, edit it and send it on.
req.ParseForm()
// edit form
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm

Ajax Post Request with Flask

I am using AJAX to send a POST request to a Flask route, but I don't know how to get the post data in a format I can read.
My route looks like this:
#app.route("/sendinvites", methods=["POST"])
#login_required
def sendinvites():
print(request.get_data("emails"))
return jsonify("done")
My AJAX looks as:
$.ajax({
type: "POST",
dataType: "json",
url: "/sendinvites",
data: { emails : emails, usernames: usernames },
success: function(data) {
console.log(data)
}
});
An example of the data sent in the emails variable is:
0: Object { id: undefined, username: "me#mydomain.com" }
An example of the output from the route is:
b'emails%5B0%5D%5Busername%5D=me%40mydomain.com'
Does anyone know how I can get the post data into a dictionary object so it is easier to process?
There are many ways to do this, but first, verify that the request contains a valid JSON.
request.get_json()
request.get_json(silent=True)
With silent=True set, the get_json function will fail silently when trying to retrieve the JSON body. By default, this is set to False.
jsonify(request.json)
This will return the entire request object. You'll have to extract the required part by specifying the key posted while sending the request in your ajax code.
Refer this for Flask part, thread
Refer this for Ajax part, thread

Ajax request error with elasticsearch

I simple make get req with ajax to elasticsearc to get all indices,
in browser it works here:
its same in my ajax, I expected the json data in browser return to my success method but failed:
Response is not JSON, you can change the response to a JSON in your server program.
It should work if you replace json by jsonp in your dataType parameter, like this:
$.ajax({
url: "http://localhost:9200/dicoms/dicoms/_search",
dataType: "jsonp", <--- change this
type: "GET",
success: function(data) {
...
});

Why is ajax parsing json to the form "a=b&c=d"?

$.ajax({
url: '/metadata/hg_billing_cycle',
data: {"a":"b", "c":"d"},
datatype: "json",
contentType: "application/json",
type: 'POST',
error: handleError,
});
I'm using ruby on the server:
post "/" do
puts "ummm: #{request.body.read}"
end
I get the following output:
ummm: a=b&c=d instead of ummm : {"a":"b", "c":"d"}. Why is it doing this?
You are passing an object as the data parameter, from the $.ajax docs
data
Type: PlainObject or String
Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below).
So your object is converted to a query string.
If you want to send json, then you'll have to well send json.
Convert your object to json (with JSON.stringify) and pass that as the data parameter.
$.ajax({
url: '/metadata/hg_billing_cycle',
data: JSON.stringify({"a":"b", "c":"d"}),
datatype: "json",
contentType: "application/json",
type: 'POST',
error: handleError,
});

Malformed JSON response being sent by Play Server

I am using jquery Ajax to send data to the client and get reply from the Client.
I am using Play Framework as backend.
AJAX:
$.ajax({
type: "GET",
url: '/authenticate',
data: {'type':type, 'redirectURL':getRedirectURL},
contentType: "application/json; charset=UTF-8",
dataType: 'json'
}).success(function( msg, txtStatus, jqXHR) {
console.log("asdasd5= "+msg);
console.log("asdasd5= "+msg.authUrl);
console.log("asdasd5= "+jqXHR.authUrl);
window.location = msg;
});
SERVER DATA CREATION:
response.setContentTypeIfNotSet("text/plain; charset=UTF-8");
Logger.info("response content type ="+response.contentType);
renderJSON("{\"authUrl\": " + authUrl +"}");
The server is sending something like "www.mywebsite.com/yoohoo/auth/1231"
But the response received by Ajax is �����������������{"authUrl": www.mywebsite.com/yoohoo/auth/1231}
DUE to these weird character the JSON response received cannot be parsed by jQuery.
Kindly, help on this.
Thanks
I noted that you are sending back (server-side) a MIME type of "text/plain". Perhaps switch to "application/json". Additionally, you could take the return string and strip any junk from the string before parsing the JSON out on the client side. This would help sanitize in case you change something again server-side and accidentally introduce new/different "junk".

Resources