by Njål

String replaceAll in Javascript

imageIn Javascript the string.replace(“target”, ”replacement”) function only replaces the first occurrence of the target…

Here’s how you can add a replaceAll() metod to all Strings (similar to Extension Methods in C#).

String.prototype.replaceAll = function (orig, replacement) {
    return this.split(orig).join(replacement);
}

 

You can then write (anywhere in your code):

"a a b c".replaceAll("a","X"); //==> "X X b c"
by Njål

CORS = XmlHttpRequest to other servers – without JSONP

 

imageAs Webstep guru Thor Halvor explained in the this excellent blogpost – there are security restrictions to prevent/limit cross domain access of XMLHttpRequest’s – the cornerstone of AJAX.

Flash and silverlight has the same restrictions – and solves this by using crossdomain.xml and clientaccesspolicy.xml. These files are placed on the server you want to communicate with – and must contain * or the domain you want to contact the server from.

Anyways – there is a similar mechanism that XMLHttpRequest supports. This mechanism is called CORS – Cross-origin resource sharing. It is a newer(2004) and preferred alternative to JSONP – and works more or less like the xml files mentioned above. The only difference is that it isn’t implemented as a file – it’s part of the HTTP Header. This makes it a bit more difficult to set up than the others.

When a javascript on siteA wants to make a request to siteB – then the script first makes an initial OPTIONS request to site B – and looks at the HTTP Header it receives.

Access-Control-Allow-Origin: *

 

If the value is * – then it means that XmlHttpRequests can communicate with that site – from any other server – and a regular XMLHttpRequest can be made just like you were communication with your own server. You can of course type in domain names here to prevent everybody from using your API.

Here’s how to configure this on an Microsoft IIS Server – Web.Config – under the <configuration> node

<system.webServer>
  <httpProtocol>
    <customHeaders>
       <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

 

So to sum it up: use CORS whenever possible, instead of hacking your way around with JSONP. You’ll have prettier code, better error handling and it’s safer to use with regard to XSS Attacks as far as I have understood. Also – CORS supports all types of HTTP requests (Get/Post/Put,Delete), while JSONP only supports Get.

Read more about CORS here:
http://my.opera.com/core/blog/2011/10/28/cors-goes-mainline

A third (and the newest) alternative is UMP – I might blog more about this some other time.

by thorhalvor

JSONP in ASP.NET MVC 3

When consuming a JSON REST API using AJAX the message is send as a XMLHttpRequest. Due to security reasons this is not allowed cross domain. Instead of returning the data as core JSON, JSONP is often used. The data will then not be parsed by the JSON parser but evaluated by the JavaScript interpreter.

Returning JSONP data does not come out of the box in ASP.NET MVC 3, but you can write a simple wrapper like this:

using System.Web.Mvc;
 
public class JsonpResult : JsonResult
{
    private const string CALLBACK_QUERYSTRING = "callback";
    private const string CALLBACK_CONTENTTYPE = "application/x-javascript";
 
    public override void ExecuteResult(ControllerContext controllerContext)
    {
        if (controllerContext != null)
        {
            var request = controllerContext.HttpContext.Request;
            object callback = request[CALLBACK_QUERYSTRING];
            if (callback == null)
            {
                controllerContext.RouteData.Values.TryGetValue(CALLBACK_QUERYSTRING, out callback);
            }
 
            var hasCallback = !string.IsNullOrWhiteSpace(callback ==null ? "" : callback as string);
 
            if (hasCallback)
            {
                SetContentTypeIfEmpty();
                var response = controllerContext.HttpContext.Response;
 
                response.Write(callback);
                response.Write("(");
                base.ExecuteResult(controllerContext);
                response.Write(")");
            }
            else
            {
                base.ExecuteResult(controllerContext);
            }
        }
    }
 
    private void SetContentTypeIfEmpty()
    {
        if (string.IsNullOrWhiteSpace(base.ContentType))
        {
            base.ContentType = CALLBACK_CONTENTTYPE;
        }
    }
}

 

It is now possible to just replace the jsonresult with jsonpresult in the code. If no callback is given it will work as normal.

        //return new JsonResult();
        return new JsonpResult();

 

When sending the request GET http://localhost/Website/Products/All?callback=myCallbackFunction the data will be wrapped like this: (same method used in last blogpost)

jsonp