Forwarding POST request data in Golang - ajax

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

Related

Ajax post request can't get data with express router

I'm using express.Router() to manage my routes.
then using Ajax post request send some data to it. but I can't get the data.
ajax code :
$.ajax({
url: '/custom',
type: 'POST',
contentType: 'application/json; charset-utf-8',
dataType: 'json',
processData: false,
data: JSON.stringify({ "key": "values" }),
success: function(data) {
console.log(data.toString());
}
})
express code:
var express = require('express');
var router = express.Router();
router.post('/custom', function(req, res) {
console.log(req.body);
console.log(req.params);
console.log(req.query);
res.write(JSON.stringify());
res.end();
});
but all the logs are empty.
The issue is because the content-type header in your ajax is malformed.
Instead of
contentType: 'application/json; charset-utf-8' it should be contentType: 'application/json; charset=utf-8'.
Assuming you are using the bodyParser.json() middleware, this would cause the body to not be parsed, which would print an empty body. When you sent the requests with Postman the proper headers were sent, which is why it worked there but not from the ajax request.

get the information from Naver LINE API through http request

I have a question on the chat app, Naver LINE. There is an API that provides login authentication called LINE login.
I've follow the instructions on the documents and run the querystring and I got a callback URL that gives me the code look like this,
https://sample.com/callback?code=b5fd32eacc791df&state=123abc
Now, the document says I need to use the code in a http request using post method. I got the following,
XMLHttpRequest cannot load https://api.line.me/v1/oauth/accessToken/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://xxxxxxxxxxxxxxxxxxxxxxxxxxx' is therefore not allowed access. The response had HTTP status code 404.
Below is the request I wrote,
$.ajax({
url: "https://api.line.me/v1/oauth/accessToken/",
type: "POST",
xhrFields: {
withCredentials: true
},
crossDomain: true,
data: JSON.stringify(data),
dataType: "json",
success: function (response) {
var resp = JSON.parse(response)
alert(resp.status);
},
error: function (xhr, status, state, error) {
alert("error", xhr, status);
console.log(xhr);
console.log(status);
console.log(state);
console.log(error);
}
});
data is the credentials I put in so LINE would pass me the user's information.
Is there anything I did wrong? If so, how can I fix this?
Thanks ahead.

Ajax request what?

So I have a stupid question about this:
$.ajax({
type: "GET",
url: `URL`,
data: DO STUFF WITH WHAT I GOT FROM THE REQUEST???,
});
In ajax, when I make a get request from a URL, with the data: parameter am I giving a response that is data or is data the data I received from the request?
You can do something with the data in the success part of the ajax call:
$.ajax({
dataType: 'json',
url: url,
data: data,
success: success
});
In this case, a potential success callback would look like this:
function success(data) {
// do something with data, which is an object
}
or if there is no data to send:
function testAjax(handleData) {
$.ajax({
url:"getvalue.php",
success:function(data) {
handleData(data);
}
});
}
The main thing to understand here is that any AJAX call (any web request really) has two components: A request and a response. The actual $.ajax() function call is sending the request, and a callback function is provided to handle the response.
To illustrate:
$.ajax({
type: "GET", // request type
url: "http://www.example.com/someResource", // destination URL
data: { name: "David", location: "Boston" } // data to send
});
This would make a GET request to the specified URL, sending it the specified data. The response in this case is ignored, since no callback is provided. But you can provide one:
$.ajax({
type: "GET",
url: "http://www.example.com/someResource",
data: { name: "David", location: "Boston" }
}).done(function(response) {
// handle the response
});
The function which contains "handle the response" will be called by the system when the AJAX response is received from the server. The response variable (or whatever you want to call that variable, the name doesn't matter) will contain whatever the server sent in return. Which could be anything, really.

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

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

wcf service json 400 Bad Request

I get a 400 Bad Request error when I try to call WCF service from client side using ajax. Following is my code,
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json)]
string[] GetUser(string Id);
$.ajax({
type: "POST", //GET or POST or PUT or DELETE verb
url: "http://localhost:58055/Service1.svc/GetUser",
crossDomain: true,
data: '{"Id": "3"}',
contentType: "application/json; charset=utf-8",
dataType: "json", //Expected data format from server
processdata: true, //True or False
success: function (msg) {//On Successfull service call
alert(msg.GetUserResult[0]);
console.log("success " + msg);
},
error: function (msg) {//On Successfull service call
console.log(msg);
}
});
Any insights would be really helpfull...
The first thing you should try is hit the URL using fiddler(so that you could post your data too) and see if you get the same error.
Are you making a cross domain request. From the example it looks like you are not. Could you remove
crossDomain: true,
line and try the jquery again.
There are other options also which unnecessay like processdata. Suggest you to use the following code and see if it works or not.
$.ajax({
type: "POST",
// the url to the service -
url: "url",
// the format that the data should be in when
// it is returned
contentType: "json",
data: '{"Id": "3"}',
// the function that executes when the server
// responds to this ajax request successfully
success: function(data) {
// put the JSON response in the employees table
}
According to the ajax api documentation the default content type is 'application/x-www-form-urlencoded'. When sending JSON, the content type should be 'application/json; charset=utf-8' except that WCF does not like that. I got the same error messages and when I removed the content type I stopped getting this error. By the way, I noticed that you set crossDomain to true, this other question is relevant to that option.

Resources