Calling SharePoint Web Services From Javascript

From SharePoint Knowledge Base

Jump to: navigation, search

This article describes how to work with SharePoint's web services from Javascript. This is very useful when creating SharePoint applications where you don't have the ability to deploy server-side code.

These code samples uses the Prototype Javascript library. When you see Ajax.Request, that’s using prototype’s Ajax framework. The great thing about prototype is that everything is cross-browser compatible.

First we need some code that formats a simple SOAP envelope. SOAP is the required protocol for communicating with the SharePoint web service.

var Soap = {
  createEnvelope: function(action, ns, parameters){
    var soap = '<?xml version="1.0" encoding="utf-8"?>
      <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
      <soap12:Body>';
    soap += '<' + action + ' xmlns="' + ns + '">';
    soap += Soap.__parseParameters(parameters);
    soap += '</' + action + '></soap12:Body></soap12:Envelope>';
    return soap;
  },

  __parseParameters: function(parameters){
    var params = "";
    if (typeof parameters == 'object'){
      // check if we were provided an array or an object
      if (typeof parameters.push == 'function'){
        for (var i = 0, length = parameters.length; i < length; i += 2){
          params += "<" + parameters[i] + ">" + parameters[i+1] + "</" + parameters[i] + ">";
        }
      }else{
        $H(parameters).each(function(pair){
          params += "<" + pair.key + ">" + pair.value + "</" + pair.key + ">";
        });
      }
    }
    return params;
  }
}

Okay, so now we can make a SOAP envelope as simple as this:

var mySoap = Soap.createEnvelope(
  "MyAction",
  "http://schemas.microsoft.com/sharepoint/soap/",
  { param1: "value", param2: "value" });

Simple enough. Now let’s call a SharePoint web service. We’ll use the Lists web service and create a new list item. The UpdateListItems method allows us to pass in some XML defining the items to create. So first I’m going to build that XML.

var batch = '
  <Batch OnError="Continue">
    <Method ID="1" Cmd="New">
      <Field Name="ID">New</Field>
      <Field Name="Title">Hello World</Field>
    </Method>
  </Batch>';

Next we’ll call the web service using the Ajax.Request object:

// build parameter object
var parameters = {
  listName: "My List",
  updates: batch       // xml created earlier
}

// create soap envelope
var soap = Soap.createEnvelope(
  "UpdateListItems",
  "http://schemas.microsoft.com/sharepoint/soap/",
  parameters);

// call web service
new Ajax.Request(
  "http://myserver/mysite/_vti_bin/lists.asmx",
  {
    method: "post",
    contentType: "application/soap+xml",
    postBody: soap,
    onSuccess: function(transoprt) { alert("Success: " + transport.responseText); },
    onFailure: function(transport) { alert("Error: " + transport.responseText); }
  });

If all goes according to plan, I should have a new list item with the title of “Hello World” in the list called “My List”.

As far as permissions are concerned, the deal with SharePoint's web services is that they can be accessed by anybody who can access the web UI. However, the action that a user is attempting to perform must be one they would be able to do through the web UI. The web services respect all security that the standard web UI does. This is great because it means that we don't need any elevated permissions to call the web services from javascript, and anything we attempt to do will be validated by SharePoint permissions before being executed.

A couple of points about the javascript above:

  1. It’s certainly not the greatest Javascript in the world. I plan to clean it up and hopefully release a Javascript library for working with all of SharePoint’s web services.
  2. The user’s browser must already be authenticated for this to work. Prototype doesn’t have a way to pass credentials to the web service so make sure you run this from a machine joined to the same domain as the sharepoint site. Ideally this is running within a sharepoint site so that should take care of the authentication problem.
  3. FireFox has an issue because it doesn’t pass domain credentials automatically. This makes debugging hard from your workstation, but if it’s running on a SharePoint site where the user has already authenticated, it works fine.
  4. I cheat in the example above and break strings onto multiple lines. That’s for the purpose of formatting only. If you copy and paste this code directly it won’t work.

You can download the code here: wsswebservice.js.

Personal tools