Best ajax questions in March 2011

Advanced jQuery/Ajax books or tutorials online

13 votes

Hello,

To begin with, I believe I know jquery basics quite well. I want to learn more and be able to make more complex things (like live chat with many features or something like that).

So, can anyone suggest me good jQuery books or tutorials online to help me become really advanced in this field.

I have an idea and I want to make it as optimal and clever as possible.

Thank you very much.



Ajax Security (i hope)

9 votes

Hi guys, I'm building a browser game and im using a heavy amount of ajax instead of page refreshs. I'm using php and javascript. After alot of work i noticed that ajax isnt exactly secure. The threats im worried about is say someone wants to look up someones information on my SQL server they'd just need to key in right information to my .php file associated with my ajax calls. I was using GET style ajax calls which was a bad idea. Anyways after alot of research i have the following security measures in place. I switched to POST (which isnt really any more secure but its a minor deterent). I have a referred in place as well which again can be faked but again its another deterrent.

The final measure i have in place and is the focus of this question, when my website is loaded i have a 80 char hex key generated and saved in the session, and when im sending the ajax call i am also sending the challenge key in the form of

challenge= <?php $_SESSION["challenge"]; ?>

now when the ajax php file reads this it checks to see if the sent challenge matchs the session challenge. Now this by itself wouldnt do much because you can simply open up firebug and see what challenge is being sent easily. So what I'm having it do is once that challenge is used it generates a new one in the session.

So my question is how secure is this from where im standing it looks one could only see what the challenge key was after it was sent and then it renews and they couldnt see it again until it is sent, making it not possible to send a faked request from another source. So does anyone see any loop hole to this security method or have any addition thoughts or ideas.

See the answer by 'meagar'.

I'd like to mention:

By passing around an identifier in Session, you're doing what the Session is already doing. There's usually a cookie with a unique identifier similar to the one you're generating, which is telling your application, essentially, who that person is. This is how PHP sessions work, in general.

What you would need to do, in this case, is check that for a given request - POST or GET - that the particular user (whose unique user ID, or similar, is stored in the Session) has permission to add/change/delete/whatever with that particular request.

So for a "search" request, you would only return results that User X has permission to view. That way, you don't worry about what they send - if the user doesn't have permission to do something, the system knows not to let them do it.

Hence "you should be authenticating all requests".

Someone feel free to add to this.

Scaling a chat app - short polling vs. long polling (AJAX, PHP)

8 votes

I run a website where users can chat with each other through the browser (think Facebook chat). What is the best way to handle the live interaction? (Right now I have a poll going every 30 seconds to update online users and new incoming messages, and another poll going on chat pages every second to get new messages.)

Things I've considered:

  • HTML5 Web Sockets: didn't use this because it doesn't work in all browsers (only chrome).
  • Flash Sockets: didn't use this because I wanted to eventually support mobile web.

Right now, I am using short polling because I don't know how scalable AJAX long polling would be. I'm running a VPS server from servint right now (running apache). Should I use long polling or short polling? I don't need absolutely immediate response times (just "good enough" for a chat app). Is short polling this often with a few hundred-thousand users going to kill my server? How do I scale this, please help!

A few notes:

  • Polling every second is overkill. The app will still feel very responsive with a few seconds of delay between checks.
  • To save your db's traffic and speed responses, consider using an in memory cache to store undelivered messages. You could still persist messages to the db, the in memory cache would simply be used for queries for new messages to avoid queries to the db every x seconds by each user.
  • Timeout the user's chat after x seconds of inactivity to stop polling to your server. This way someone leaving a window open won't continue to generate traffic. Offer a simple "Still there? Continue chatting." link for sessions that timeout and warn user before the timeout so they can extend the timeout.
  • I'd suggest starting out with polling rather than comet/long polling/sockets. Polling is simple to build and support and will likely scale just fine in the short-term. If you get a lot of traffic you can throw hardware and a load balancer at the problem to scale. The entire web is based on polling - polling most certainly scales. There's a point where the complexity of alternatives like comet/long polling/etc make sense, but you need a lot of traffic before the extra development time/complexity are justified.

auto_complete_for: prevent the first item from being auto-selected

8 votes

The auto_complete_for dealio from script.aculo.us is great an all, but is there a way for me to selectively disable the fact that it always auto-selects the first item in the list?

The problem is that, if I want to type my own entry that is new, and novel, I don't want the first item in the list to be auto-selected. The reason is because when I TAB out of the field, it selects, and fills the text box with that first item.

I got around that, somewhat, by making the first item in the list the same as what I'm typing, but that's not perfect either, because the auto_complete list doesn't always update with every keystroke, depending on how fast I type. I've tried setting the list refresh rate to the lowest value (1 millisecond) but no go.

What I really want is an option in "auto_complete_for" that doesn't select that first item at all - the same way that Google Instant doesn't automatically select the first suggested search phrase - you have to arrow-down to select one.

Maybe I can do this via an HTML option that I'm missing?

Looking at the source, there doesn't appear to be an option for that, but I bet if you changed line 284 of controls.js to this.index = -1; it would do what you want.

Otherwise, it might be time to look for a different autocomplete widget.

XmlHttpRequest onprogress interval

8 votes

I'm using XmlHttpRequests to upload images to a server and I'd like to show the user the progress of these uploads.

Unfortunately the interval between calls to my onprogress-event handler is too large. Usually onprogress is called only once or twice for a 500k image.

Here is my code:

/* This function is not called often enough */
function progress(e){
    msgq.message(id, 'Uploading ' + imgName + ': ' + Math.round((e.loaded / e.total) * 100) + ' %')
}

var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', progress, false);
xhr.send(data);

Can this behaviour be changed or is this hardcoded somewhere in the browser implementation?

The W3 sets forth the following guidelines in their XMLHttpRequest Level 2 document. Obviously varying levels of conformance across browsers are to be expected.

Uploads:

While the request entity body is being uploaded and the upload complete flag is false, queue a task to fire a progress event named progress at the XMLHttpRequestUpload object about every 50ms or for every byte transmitted, whichever is least frequent. - W3 XMLHttpRequest Level 2 (Bolded for emphasis)

Downloads:

When it is said to make progress notifications, while the download is progressing, queue a task to fire a progress event named progress about every 50ms or for every byte received, whichever is least frequent. - W3 XMLHttpRequest Level 2 (Bolded for emphasis)

I am not aware of an api to customize this functionality.

Any way to make {% extends '...' %} conditional? - Django

7 votes

Hi,

I would like to share a template between AJAX and regualr HTTP calls, the only difference is that one template needs to be served with the base.html html, the other one without.

Any idea?

Use a variable.

{% extends base_template %}

and in your view, set it to "base.html" in your view, or a new "ajax.html" file which just provides the block and nothing else.

Is there an advantage to dynamically loading/unloading javascript and css stylesheets?

6 votes

Background:

I'm putting together a site that will use ajax as a primary method of changing the content. That way the main frame and images will not have to be constantly reloaded with every page change. The main frame has its own site.css stylesheet.

Question 1:

Is it worthwhile to put all the stylesheet information into a single stylesheet? I think that this would make the website less modular. Everytime a new page or content is added/removed the css would have to be updated (given the content requires different style information).

Question 1.1:

Same question but with javascript.

Question 2:

If it is worthwhile (as I think it is) to have multiple stylesheets, is it beneficial to unload a stylesheet when its not in use. For example, I load the profile.php page so I dynamically load the profile.css. The user then changes to the settings.php page, I unload the profile.css and load the settings.css. Is this constant loading/unloading going to tank performance or even save on website size?

Question 2.1

Same question as above but applied to javascript functions.

Once your javascript or css file is downloaded to the machine, it is cached by their browser. So, you don't incur the additional cost of another HTTP request. Lazy loading the scripts and stylesheets could make sense, but there is no sense in unloading these web assets once they have already been sent to the client.

It is good to use some sort of mechanism to compile your scripts and stylesheets to minimize the initial http requests to one per asset type. Having only one stylesheet and one javascript file would be an architectural nightmare in many cases, but that doesn't mean that you can't still present it to the browser that way. I use .NET, so I'm not sure how you handle this in PHP, but I'm sure the functionality is out there.

Cross domain POST query using Cross-Origin Resource Sharing getting no data back

6 votes

I'm sending data cross domain via a POST request but the response isn't working, specifically, jQuery's success handler never gets called.

Stuff being used: Django, Apache, jQuery.

So, I set up a request rather similar to this:

$.ajax({
    url: "http://somesite.com/someplace",
    type: "POST",
    cache: false,
    dataType: "json",
    data: { ... },
    success: function( msg ) {
        alert(msg);
    },
});

As you well know, CORS allows me to respond to an OPTIONS query appropriately to say "Yes, you can POST to me". Which I'm doing. Firebug confirms I'm getting my 200 status code and that the return type is in fact application/json. However, Firebug also confirms that the success handler in the above is not being called.

For reference, my response to OPTIONS is:

elif request.method == "OPTIONS":
    response = HttpResponse("")
    response['Access-Control-Allow-Origin'] = "*"
    response['Access-Control-Allow-Methods'] = "POST, GET, OPTIONS"
    response['Access-Control-Allow-Headers'] = "X-Requested-With"
    return response

In contrast, if I set up a complete: function()... handler it works.

So, question is: what's happening (or not) and why? I am getting data fine, I'd just like to be able to return the response.


Update: This fixes my issue on some browsers but since I don't have a complete definite explanation to this behaviour I'm leaving it open.

Ok, so I read the manual and what I understand of it, the algorithm applied is roughly this:

  1. User agents may implement a preflight call. This is the OPTIONS request. The idea is that they make this request which gives them an answer with respect to the requested resource, which they are then supposed to cache. I'm not passing back a max-age field, so I suspect whilst success is being returned and the X-request allowed, there is nothing in the user agent's cache which permitted me to make it, so the default rules (isolate the request) are applied.
  2. When you make the actual request, I believe the user agent is supposed to inspect the pre-flight cache for permissions. Without my max-age field, I believe it isn't finding these permissions. However, responding with the same headers on POST appears to allow Firefox and Google Chrome to view the response. Opera can not. IE remains untested at the moment.

I do not currently understand and it is not clear from the manual (to me at least) whether a CORS request should also answer with these headers in the request as well as the OPTIONS. I shall experiment with the Max-Age header and see what that allows or does not allow. However, I'm still short of some definite authoritative understanding on the issue so if there is someone on here who knows, I'm all ears.

Ok, so I believe the correct way to do things is this:

if request.method == "POST":
    response = HttpResponse(simplejson.dumps(data),mimetype='application/json')
    response['Access-Control-Allow-Origin'] = "*"
    return response
elif request.method == "OPTIONS":
    response = HttpResponse("")
    response['Access-Control-Allow-Origin'] = "*"
    response['Access-Control-Allow-Methods'] = "POST, OPTIONS"
    response['Access-Control-Allow-Headers'] = "X-Requested-With"
    response['Access-Control-Max-Age'] = "180"
else:
    return HttpResponseBadRequest()

This is based on the documentation I dug up from Mozilla on preflighted requests.

So, what I believe will happen is this:

  1. If there's nothing in the preflight cache, OPTIONS is sent with X-Requested-With set to XMLHttpRequest I believe this is necessary to allow Javascript access to anything, along with an Origin header.
  2. The server can examine that information. That is the security of CORS. In my case, I'm responding with "any origin will do" and "you're allowed to send the X-Requested-With thing". I'm saying that OPTIONS and POST are allowed and that this response should be cached for 30 mins.
  3. The client then goes ahead and makes the POST, which was working before.
  4. I modified the response originally to include Allow-Methods and Allow-Headers but according to the exchange in the above linked documentation this isn't needed. This makes sense, the access check has already been done.
  5. I believe then that what happens is the resource sharing check described here. Basically, once said request has been made, the browser again checks the Allow-Origin field for validity, this being on the request such as POST. If this passes, the client can have access to the data, if not, the request has already completed but the browser denies the actual client side application (Javascript) access to that data.

I believe that is a correct summary of what is going on and in any case it appears to work. If I'm not right, please shout.

"Editing" user text on the fly?

6 votes

Hi guys,

I would like to implements something like vBullettin (or stackoverflow) does. When the user clicks "edit" the HTML text is converted to plain text into a <textarea></textarea> ready for the editing.

How would you implemeent something like that? Note I can use jQuery.

I would like especially know the authentication part (if users clicks "edit" on soemone else comments there is a warning)

Thanks

Check out this jQuery plugin for inline editing

http://www.appelsiini.net/projects/jeditable

How to create a default AjaxOptions for Razor Views?

6 votes

How do I create a default AjaxOptions? For example, I have a menu with some links, I want to make the entire website to use the same loading element and same error handling.

@Ajax.ActionLink("Home", "Index", "home", <AjaxOptions>)

new AjaxOptions()
{
    OnFailure = "handleError",
    LoadingElementId = "loading"
});

But then I have some links that update the content and I want to set UpdateTargetId for each of those links. How can I keep a default error handling and loading element on all the views and edit only UpdateTargetId or OnSuccess (or another property) for each link?

Something like

@Ajax.ActionLink("home", "Index", "home", ajaxOption.UpdateTargetId = "content")
@Ajax.ActionLink("menu", "Foo", "home", ajaxOption.UpdateTargetId = "side-content")

I want something equivalent to jQuery.setup where I can set the default values to ajax requests and when I make an ajax request I only tell the parameters I want to override...

You could do something like:

public static class AjaxExtensions
{
    public static IHtmlString DefaultLink(this AjaxHelper helper, string text,
        string action, string controller, string updateTargetId = "", 
        string onSuccess = "")
    {
        // Build your link here eventually using 
        // the arguments passed
        var options = new AjaxOptions
        {
            OnSuccess = onSuccess,
            UpdateTargetId = updateTargetId,
            OnFailure = "handleError",
            LoadingElementId = "loading"
            // etc...
        }

        // return a normal ActionLink passing your options
        return helper.ActionLink(text, action, controller, options);
    }
}

Note I'm using optional parameters in the signature to benefit from the flexibility of multiple overloads without the nuisance of maintaining them. Expand as needed :)

Then just use it as follows:

@Ajax.DefaultLink("home", "Index", "home", updateTargetId: "content")

What is the life span of an ajax call?

6 votes

let's say I have this code in javascript:

function doAnAjaxCall () {
    var xhr1 = new XMLHttpRequest();
    xhr1.open('GET', '/mylink', true);
    xhr1.onreadystatechange = function() {
        if (this.readyState == 4 && this.status==200) {
            alert("Hey! I got a response!");
        }
    };
    xhr1.send(null);
}

and let the code in the servlet be:

public class RootServlet extends HttpServlet {
    public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.getWriter().write("What's up doc?");
        resp.setStatus(200);
    }
}

Will xhr1 still wait for new changes in readystate? Or it is closed as soon as it gets the first response? If it remains open, will it lead to memory leaks/slower browser after a while and accumulating a few of those? Should I always call resp.getWriter().close() at the end of the servlet code?

And, lastly, for the jQuery fans out there:

does $.ajax() behave as XMLHttpRequest() in that respect?

Will xhr1 still wait for new changes in readystate? Or it is closed as soon as it gets the first response? If it remains open, will it lead to memory leaks/slower browser after a while and accumulating a few of those?

Behind the scenes, it remains open. It (and the memory occupation) is however the responsibility of the webbrowser engine. It maintains a certain amount of connections in a pool which has a maximum limit per domain anyway. MSIE for example has a bug which causes them to leak away when they are still running while the user unloads (closes) the window.

Should I always call resp.getWriter().close() at the end of the servlet code?

Not necessary. The servletcontainer will close it anyway. Closing it yourself only prevents the risk of some (buggy) code further in the response chain from writing to the response body. For more detail, see this answer.

And, lastly, for the jQuery fans out there: does $.ajax() behave as XMLHttpRequest() in that respect?

It uses XMLHttpRequest under the covers (only when supported by the browser; otherwise it's the MSIE ActiveX object). It constructs a new one on every call. Open the unminified source code, Ctrl+F the jQuery.ajaxTransport( function. All the ajax handling code is almost 200 loc and it covers all possible browser specific bug fixes you can think about.

Adding exactly 100 values to database using ajax

5 votes

Hey guys, 3:36am and I'm needing a mental boost.

Simple question, what is the easiest/fastest way to add 100 points to a database. Please assume all writes will not work due to duplicates, bad data, etc.

I'm trying to update a database with exactly 100 values.

Once I have a good piece of data, I need to add it to the database and I use a function called updateDB.

This function just writes a lat/lng coordinate to the database. If there is a duplicate or the write fails, I send "error" from php and the loop should continue collecting data until I have exactly 100 points to the database. Here's the function I'm using.

cct is used for xss prevention, please ignore it, this works fine.

////more above this
if(100-completed > dispatched)
    dispatched++;
    updateDB(lat,lng);
/// more junk and then this function
function updateDB(lat,lng)
{
    var cct = $("input[name=csrf_mysite]").val();
    $.ajax({
        type: "POST",
        url: "/form",
        data: { 
            'lat': lat,
            'lng': lng,
            'id_set': id_set,
            'csrf_complexity': cct },
        success: function(result) {
            var obj = jQuery.parseJSON(result);
            if( obj.status === "OK" )
            {
                completed++;
                var marker = new google.maps.Marker(
                {
                    icon: markerIcon,
                    position: new google.maps.LatLng(lat, lng),
                    map: map
                });
                $( "#progressbar" ).progressbar( "option", {
                    value: completed,
                    max: 100
                });
                $("#amount").text("Getting image " + completed + " of 100");
            }
        },
        error: function(data){
            //alert(data.responseText);
            },
        complete: function(data){
            if(completed == 100)
                window.location = "/start/curate";
            dispatched--;
        }
    });
}

This function does not work. So any idea why?

It should work simply. Call updateDB until it either reaches 100 added values and only call updateDB when there is no possibility that there will be extra calls. Dispatch does not decrement properly so I'm assuming complete isn't called on every event.

Ideas? Or any other way to do this would be awesome.

Write your server side script to respond with a figure - Then in the first request you sent 100 data points:

Browser             Server
  |                   |
  |---> 100 data ---> |
  |<- send 20 more <- |
  |                   |
  |--->  20 data ---> |
  |<- send  1 more <- |
  |                   |
  |--->  1  data ---> |
  |<- send  0 more <- |
  |                   |
  v                   v

Like that you don't get the kind of sync trouble that comes from counting at the client end how much information has been processed at the server end - the server processes the data, excludes the duplicates, ill-formed etc., and the server counts what it needs.

All the client has to do is send all it can and poll the server for how much more is needed. Also you want to send multiple points at once because of the overheads of an Ajax request, but you don't want to send much more than is actually needed, because that too is wasteful.

Hope this helps.

Ajax functions like .load() strip out comments from the HTML. How can I keep the comments?

4 votes

For example, $('#some-div').load('http://foo.bar #content') will retrieve #content from http://foo.bar but with all HTML <!--comments--> stripped.

How can I retrieve the contents of #content including any comments?

From the jQuery manual:

jQuery uses the browser's .innerHTML property to parse the retrieved document and insert it into the current document. During this process, browsers often filter elements from the document such as <html>, <title>, or <head> elements. As a result, the elements retrieved by .load() may not be exactly the same as if the document were retrieved directly by the browser.

So you should use $.get() to retrieve the HTML instead of $.fn.load()

Rewriting jQuery to plain old JavaScript - are the performance gains worth it?

4 votes

Since jQuery is an incredibly easy and banal library, I've developed a rather complex project fairly quickly with it. The entire interface is jQuery based, and memory is cleaned regularly to maintain optimum performance. Everything works very well in Firefox, and exceptionally so in Chrome (other browsers are of no concern for me as this is not a commercial or publicly available product).

What I'm wondering now is - since pure plain old banal JavaScript is really not a complicated language to master, would it be performance enhancing to rewrite the whole thing in plain old JavaScript, and if so, how much of a boost would you expect to get from it?

If the answers prove positive enough, I'll go ahead and do it, run a benchmark and report back with the precise findings.

Edit: Thanks guys, valuable insight. The purpose was not to "re-invent the wheel" - it was just for experience and personal improvement. Just because something exists, doesn't mean you shouldn't explore it into greater detail, know how it works or try to recreate it. This is the same reason I seldom use frameworks, I would much rather use my own code and iron it out and gain massive experience doing it, than start off by using someone else's code, regardless of how ironed out it is. Anyway, I won't be doing it, thanks for saving me the effort :)

You say the site works from "very well" to "exceptionally" - then don't bother. It won't be worth the effort, and there is no guarantee that your end result will even be more optimal than with jQuery, as the jQuery team has had years to iron out many issues.

You also say that plain old JS is "really not a complicated language" - that's not the main issue. It's not JS that's difficult to master, and what jQuery makes up for, but all the various browser quirks.

In the end, even if you do create a site that is marginally faster without jQuery, you have one that is much harder to maintain.

In short, there are times when doing such an exercise is valuable, but not when your site already works "very well", and it's not necessarily as simple as you think.

WCF Service returns 400 Bad Request

4 votes

Hello!

I've got this application that works locally and when deployed and using a .mdf SQL Express database file (which I usually use for testing purposes). However, when I change it to work with our SQL Server 2008 the app works but the service doesn't.

For example if in my code behind of a page I have a button that adds data to a table such as this it works fine:

public static string connString = @"Data Source=server1;Initial Catalog=Project;Integrated Security=True";

protected void btnAddProj_Click(object sender, EventArgs e)
{
    using (var sqlc = new SqlConnection(connString))
    {
        sqlc.Open();
        var cmd = sqlc.CreateCommand();
        int intProjectID;

        // Add the project info to the database
        cmd.CommandText = "INSERT INTO tblProject VALUES(@ProjName,@ProjTeam,@ProjStart,@ProjEnd)";
        cmd.Parameters.Add("ProjName", System.Data.SqlDbType.NVarChar).Value = txtProjName.Text;
        cmd.Parameters.Add("ProjTeam", System.Data.SqlDbType.Int).Value = ddlTeamSupported.SelectedValue;
        cmd.Parameters.Add("ProjStart", System.Data.SqlDbType.NVarChar).Value = txtStartDate.Text;
        cmd.Parameters.Add("ProjEnd", System.Data.SqlDbType.NVarChar).Value = txtEndDate.Text;
        cmd.ExecuteNonQuery();
    }       
}

My web.config is setup to use impersonation on that server and all works perfectly well. However, for my service the query doesn't seem to return anything and I get a 400 Bad Request error.

The code for the jquery is:

$.ajax({
    type: "POST",
    async: false,
    url: "Services/ProjectService.svc/test",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (data) {
        console.log(data);
        }
    });

And for the Service:

[ServiceContract]
public interface IProjectService
{
    [OperationContract]
    [WebInvoke(ResponseFormat = WebMessageFormat.Json)]
    ArrayList test();
}


    public static string connString = @"Data Source=server1;Initial Catalog=Project;Integrated Security=True";

    public ArrayList test()
    {
        var sqlc = new SqlConnection(connString);
        sqlc.Open();
        var cmd = sqlc.CreateCommand();
        cmd.CommandText = "SELECT ProjectID FROM tblProject";
        var reader = cmd.ExecuteReader();

        ArrayList temparray = new ArrayList();


        while (reader.Read())
        {
            temparray.Add(reader[0]);
        }
        sqlc.Close();
        return temparray;
    }

If instead of querying the database I have the service just return static data then it works fine. What could cause my service not to be able to connect to the database when the rest of the code behind for the app works?

A database connection from a hosted WCF Service is considered a remote connection so make sure your connection strings specifies the authentication method. So try using Integrated Security=SSPI in your connection string and if that doesn't work make sure that your Application Pool's Identity is set to a domain account that has permissions on the SQL server. :)

how to use jQuery ajax calls with node.js

4 votes

This is similar to Stream data with Node.js, but I don't feel that question was answered sufficiently.

I'm trying to use a jQuery ajax call (get, load, getJSON) to transfer data between a page and a node.js server. I can hit the address from my browser and see 'Hello World!", but when I try this from my page, it fails and shows that I get no response back. I setup a simple test page and hello world example to test this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>get test</title> 
</head>
<body>
    <h1>Get Test</h1>
    <div id="test"></div>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"></script>
    <script>
        $(document).ready(function() {
            //alert($('h1').length);
            $('#test').load('http://192.168.1.103:8124/');
            //$.get('http://192.168.1.103:8124/', function(data) {                
            //  alert(data);
            //});
        });
    </script>
</body>
</html>

and

var http = require('http');

http.createServer(function (req, res) {
    console.log('request received');
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(8124);

If your simple test page is located on other protocol/domain/port than your hello world node.js example you are doing cross-domain requests and violating same origin policy therefore your jQuery ajax calls (get and load) are failing silently. To get this working cross-domain you should use JSONP based format. For example node.js code:

var http = require('http');

http.createServer(function (req, res) {
    console.log('request received');
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('_testcb(\'{"message": "Hello world!"}\')');
}).listen(8124);

and client side JavaScript/jQuery:

$(document).ready(function() {
    $.ajax({
        url: 'http://192.168.1.103:8124/',
        dataType: "jsonp",
        jsonpCallback: "_testcb",
        cache: false,
        timeout: 5000,
        success: function(data) {
            $("#test").append(data);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            alert('error ' + textStatus + " " + errorThrown);
        }
    });
});

There are also other ways how to get this working, for example by setting up reverse proxy or build your web application entirely with framework like express.

Pass array to mvc Action via AJAX

4 votes

Hi team,

I'm trying to pass an array (or IEnumerable) of ints from via AJAX to an MVC action and I need a little help.

the javascript is

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {...

and the controller action is

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

At the moment the request is formatted as

controller/MyAction?_=1301503418429&arrayOfValues[]=491&arrayOfValues[]=368&arrayOfValues[]=235&arrayOfValues[]=437

So I'm almost there, if I take the square brackets off I get the correct response. How should I be passing that array into my get so that the controller can recognise what it is?

Many thanks for your help

Dave

Set the traditional property to true before making the get call. i.e.:

jQuery.ajaxSettings.traditional = true

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {...