How to do an ajax request with large parameters? - javascript

I am getting 'Request-URI Too Large' error when I tried to call a rails controller function from javascript with a large json parameter. I'm using Webrick http server. Is there any way to resolve this without changing the server?
I have something like:
$.ajax({
url: 'application/get_list',
data: { options : options_json, selected_option : selected_option_string},
success: function(data) {
// Insert the data to a div (returned data is a select tag with options)
},
type: 'get'
});

The simplest fix would be to change it to a POST request, and set up the action to handle that, and then you won't run into this error.
If you need to it to be a GET request, you can add a file called webrick.rb to the config\initializers directory with this content:
if defined?(WEBrick::HTTPRequest)
WEBrick::HTTPRequest.const_set("MAX_URI_LENGTH", 10240)
end
and if you keep getting the error, keep increasing the number 10240 until it works.
Since your comment says it needs to be a GET request, you really have no option but to set the MAX_URI_LENGTH. From the WEBrick source:
if #request_line.bytesize >= MAX_URI_LENGTH and #request_line[-1, 1] != LF
raise HTTPStatus::RequestURITooLarge
end
If you need really long URI's, then set it to something absurd, like 9223372036854775807

Related

Recieving data sent by ajax.post

I would like to send data to a Node.js server running on localhost with ajax. To test this, I wanted to send the input of type text to the server and just log it there.
This is my Post-Function (which is called by clicking on a button):
function answer(){
let data = {
name : $('#send').val()
};
console.log(data);
$.ajax({
type: 'POST',
url: 'http://localhost:3456/MyWebApp/Test',
dataType: 'text',
data: data.name,
success: console.log('post was successfull'),
error: function(textStatus, errorTrown){
console.log(textStatus + " " + errorTrown);
}
});
}
On my Server I try to collect the data with the following function:
app.post('/MyWebApp/Test', function(request,response){
console.log(request.body.data);
});
app.listen(3456);
My problem is, that the value on my server (in the above console.log) is always undefined.
I already tried to send the whole json-Object with dataType-Parameter json instead of text, but then I get an error in my server for trying to read a property value of something undefined. How do I have to implement the app.post function, to make the data readable and work with it?
I hope it is possible to understand what I am trying to achieve and what my problem is, I dont really know much about Node.js or Ajax, still I would be thankful for any help.
You're sending one string value data.name so your http request Content-Type would be plain/text
At NodeJS side you're using express library and it doesn't provide post request body by default.
You need to collect post request body using "data" event
request.on("data", callback);

Undefined index on ajax call only for one function

I have several different ajax calls on the same php page, but I get undefined index for only one function (createAlbum).
I send exactly the same parameters in each of my ajax calls. It worked fine for a few tests, but now it only works for the other ones, but not for this specific call.
I suspected that the .js file was still in the browser cache, so I cleared it and tried with other browsers, which worked for a few more attempts.
Now, I can't get it working on any browser, and definitely don't understand why.
Here is my ajax call :
$.ajax({
type: "POST",
url: BASE_URL,
data: {
action: "createAlbum",
data: JSONAlbum
},
cache: false,
success: callback
});
My php file handling the request ($_POST['action'] is always undefined with the above request) :
if (isset($_POST['action'])) {
switch ($_POST['action']) {
// Handle the action
// ...
}
} else {
echo 'ACTION : '.$_POST['action'];
}
The header containing the ajax parameters ("data" is a json containing one or more blob images, this might be the problem, but I didn't find anything saying so) :
And finally, the response containing the error :
I really hope this is not a dumb error of mine, but I asked a friend before posting, and he can't find the solution either.
Thanks for your help !
You said that the error not happens all the time (in some call yes, in other no).
The body post is sent, you see it in console. So we can exclude javascript problem.
So the problem is something that happens before or during the process.
PHP has some limitations on input vars, you can see it in php.ini.
I see that you send images in base64, so it's probable that something of these limitations are triggered.
See for example:
max_input_time
max_input_vars
post_max_size

Get jQuery $.ajax to send data in body for GET [duplicate]

The service API I am consuming has a given GET method that requires the data be sent in the body of the request.
The data required in the body is a list of id's separated by hypen and could potentially be very large and thus it must be sent in the body otherwise it will likely foobar somewhere in the browsers/proxies/webservers etc chain. Note I don't have control over the service or API so please don't make suggestions to change it.
I am using the following jQuery code however observing the request/response in fiddler I can see that the "data" I am sending is ALWAYS converted and appended to the query string despite me setting the "processData" option to false...
$.ajax({
url: "htttp://api.com/entity/list($body)",
type: "GET",
data: "id1-id2-id3",
contentType: "text/plain",
dataType: "json",
processData: false, // avoid the data being parsed to query string params
success: onSuccess,
error: onError
});
Anyone know how I can force the "data" value to be sent in the body of the request?
In general, that's not how systems use GET requests. So, it will be hard to get your libraries to play along. In fact, the spec says that "If the request method is a case-sensitive match for GET or HEAD act as if data is null." So, I think you are out of luck unless the browser you are using doesn't respect that part of the spec.
You can probably setup an endpoint on your own server for a POST ajax request, then redirect that in your server code to a GET request with a body.
If you aren't absolutely tied to GET requests with the body being the data, you have two options.
POST with data: This is probably what you want. If you are passing data along, that probably means you are modifying some model or performing some action on the server. These types of actions are typically done with POST requests.
GET with query string data: You can convert your data to query string parameters and pass them along to the server that way.
url: 'somesite.com/models/thing?ids=1,2,3'
we all know generally that for sending the data according to the http standards we generally use POST request.
But if you really want to use Get for sending the data in your scenario
I would suggest you to use the query-string or query-parameters.
1.GET use of Query string as.
{{url}}admin/recordings/some_id
here the some_id is mendatory parameter to send and can be used and req.params.some_id at server side.
2.GET use of query string as{{url}}admin/recordings?durationExact=34&isFavourite=true
here the durationExact ,isFavourite is optional strings to send and can be used and req.query.durationExact and req.query.isFavourite at server side.
3.GET Sending arrays
{{url}}admin/recordings/sessions/?os["Windows","Linux","Macintosh"]
and you can access those array values at server side like this
let osValues = JSON.parse(req.query.os);
if(osValues.length > 0)
{
for (let i=0; i<osValues.length; i++)
{
console.log(osValues[i])
//do whatever you want to do here
}
}
Just in case somebody ist still coming along this question:
There is a body query object in any request. You do not need to parse it yourself.
E.g. if you want to send an accessToken from a client with GET, you could do it like this:
const request = require('superagent');
request.get(`http://localhost:3000/download?accessToken=${accessToken}`).end((err, res) => {
if (err) throw new Error(err);
console.log(res);
});
The server request object then looks like {request: { ... query: { accessToken: abcfed } ... } }
You know, I have a not so standard way around this. I typically use nextjs. I like to make things restful if at all possible. If I need to make a get request I instead use post and in the body I add a submethod parameter which is GET. At which point my server side handles it. I know it's still a post method technically but this makes the intention clear and I don't need to add any query parameters. Then the get method handles a get request using the data provided in the post method. Hopefully this helps. It's a bit of a side step around proper protocol but it does mean there's no crazy work around and the code on the server side can handle it without any problems. The first thing present in the server side is if(subMethod === "GET"){|DO WHATEVER YOU NEED|}

AJAX call error - status of 400 (Bad Request)

I'm trying to use the BloomAPI to retrieve Doctor's NPI number by querying with their first and last name. I'm using Jquery Ajax to make a get request for the JSON data.
I am able to get the JSON data when I do CURL in the terminal: curl -X GET 'http://www.bloomapi.com/api/search?offset=0&key1=last_name&op1=eq&value1=LIN&key2=first_name&op2=eq&value2=JOHN'
For the purpose below - I just hardcoded in the params into the URL.
I get a "Failed to load resource: the server responded with a status of 400 (Bad Request" Error. Any idea what I might be doing wrong?
$.ajax({
type: 'GET',
url: 'http://www.bloomapi.com/api/search?offset=0&key1=last_name&op1=eq&value1=LIN&key2=first_name&op2=eq&value2=JOHN',
dataType: 'jsonp'
}).done(function(server_data) {
console.log(server_data)
}).fail(console.log("failed"));
This was a weird one... your code is actually basically correct, however, it appears bloomapi does not support disabling caching in the way jquery does it.
When you make the jquery call you have, the actual url becomes something like this:
http://www.bloomapi.com/api/search?offset=0&key1=last_name&op1=eq&value1=LIN&key2=first_name&op2=eq&value2=JOHN&callback=jQuery111207365460020955652_1428455335256&_=1428455335257
The callback is a jsonp construct, and the _ is a way of breaking caching. However, bloomapi appears to not like this:
jQuery111207365460020955652_1428455335256({"name":"ParameterError","message":"_ are unknown parameters","parameters":{"_":"is an unknown parameter"}});
To get around this, you can disable cache busting like so:
$.ajax({
type: 'GET',
url: 'http://www.bloomapi.com/api/search?offset=0&key1=last_name&op1=eq&value1=LIN&key2=first_name&op2=eq&value2=JOHN',
dataType: 'jsonp',
cache: true
}).done(function(server_data) {
console.log(server_data)
}).fail(function() { console.log("failed") });
You will have to be careful of how else you break the cache if that's an issue; the api provider may be able to provide feedback on how to do this.
In the future, you can easily check the errors you are receiving/what you are sending using a web debugger; I used Fiddler to figure this out.

crossDomain jquery ajax not getting json

I simply created a rails 3.0 scaffold and exposed it using json, and kept it running.
So if I hit http://localhost:3001/objects.json
I see json data in browser
Next I have one plain html which includes code.jquery.com/jquery-1.7.min.js. I opened this page in firefox(ubuntu), then opened the firebug console and tried following
var myurl = 'http://localhost:3001/objects.json';
$.ajax({
url: myurl,
dataType: 'jsonp',
error: function(data){ console.log("error:"+data); console.log("error:"+data.readyState); },
success: function(data){ console.log("success:"+data); }
});
I wanted to fetch same json here in success handler, what I have observed so far is
if specified dataType: 'jsonp'
I do get json response(checked with firebug:Net), same as I see in browser
I do not get success called
I do get error called, with status code = 4, and status = "success"
else I get
response blank
And one more thing, every time I get 200 back.
Any hints ...whats going on here?
Adding my server side code and log
code =>
# GET /objects
# GET /objects.json
def index
#objects = Object.all
respond_to do |format|
format.html # index.html.erb
format.json {
render :json => #objects.to_json, :layout => nil
}
end
end
log sample =>
Started GET "/objects.json?callback=jQuery17024293556233345082_1321347517236&_=1321347853199" for 127.0.0.1 at 2011-11-15 14:34:13 +0530
Processing by objectsController#index as JSON
Parameters: {"callback"=>"jQuery17024293556233345082_1321347517236", "_"=>"1321347853199"}
[1m[35mobject Load (0.1ms)[0m SELECT `objects`.* FROM `objects`
Completed 200 OK in 11ms (Views: 5.4ms | ActiveRecord: 0.1ms)
I think you using $.getJSON may be better
Maybe you returning result in the wrong Content-type (not jsonp). If you want jQuery to fire 'success' event regardless the Content-type, remove dataType parameter from ajax options
First, I am guessing it should be Object.all
I am assuming that the server your requesting from is different from the server that provides you with JSON data. i.e. different ports in this case or I see no need to use JSONP.
JSONP is not ajax but uses the src attributes in the script tags. If your trying to access information from the same server it dataType: json should be the approach.
If you are fetching information from a different server i suggest you add to the end of your url stream a ?callback=?.
With Jquery $.getJSON should be the way to go. For example
$.getJSON(url, data, function(response){
// Do something with response;
});
Reference http://api.jquery.com/jQuery.getJSON/
In reference to your last comment use this format.
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
tags: "cat",
tagmode: "any",
format: "json"
},
function(data) {
$.each(data.items, function(i,item){});
});
Update
Just remembered this bit, If you have control over both servers are you sending JSONP responses? If this is your JSON data
response = { status:'success', message:'Successfully created object'}
To send it as JSONP you must wrap it up in a function(). Like
jsoncallback + "(" + JSON.stringify(response) + ");";
What this does is it executes the function generated by Jquery (this is done internally when specifiy callback=?. You can get the value by checking localhost:3001 logs) and passes your JSON data as parameters to that.
So if on the server side you are not generating JSON-P response it wont work.
We ran into a similar issue once long back, although with json, not jsonp. And it wasn't a cross-domain problem. Counting on my memory, I believe we had to remove respond_to from the controller and provide :status => 200 to render method to get it working. I'm not very sure, but you could give it a shot.

Categories