Как вы думаете, сколько способов сделать ajax запрос в SharePoint? А без jQuery и дополнительных библиотек? Нет, XMLHttpRequest руками писать на надо.

Sys.Net.WebRequest \ Sys.Net.WebRequestExecutor

Эти классы находятся в библиотеке MicrosoftAjax. Она подгружается на каждой странице SharePoint и вы можете использовать её на своих страницах.

Класс Sys.Net.WebRequest описывает параметры запроса, а Sys.Net.WebRequestExecutor, вернее его наследник, выполняет запрос с указанными параметрами. Можно создавать свои реализации WebRequestExecutor, например для тестирования или для проксирования запросов.

Недостаток этих классов в чрезмерной многословности.

var request = new Sys.Net.WebRequest();         
request.set_url(url);
request.set_httpVerb("GET");         
request.add_completed(function(executor, eventArgs) {             
    if(executor. get_responseAvailable()) {
        //do stuff
    }
});

request.invoke(); 

Вот так придется писать на каждый запрос. Семантически похоже на то, что есть в C#, но после jQuery выглядит страшно. Тем не менее этот api является базовым для всего, что работает в SharePoint.

Ссылки на MSDN:
Sys.Net.WebRequest - http://msdn.microsoft.com/en-us/library/bb310979(v=vs.100).aspx
Sys.Net.WebRequestExecutor- http://msdn.microsoft.com/en-us/library/bb397434(v=vs.100).aspx

SP.PageRequest

Этот класс находится в библиотеке sp.js и доступен с SharePoint 2010.

У нем есть два статических метода doGet и doPost.

SP.PageRequest.doGet(
    url,'application/json', 
    function(o, args) {
        var webRequestExecutor = args.get_executor();
        //do stuff
    }, 
    function(o, args) {
        //args.get_errorMessage();
    });

Аналогично работает метод doPost, который может также передавать body.

Огромный недостаток этих методов в том, что они не позволяют указать загловки запроса. А второй параметр, который называется expectedContentType, сравнивается с Content-Type результата и выкидывает исключение при несовпадении.

Конечно можно создать экземпляр SP.PageRequest, из него получить объект Sys.Net.WebRequest, и через него выставить заголовки. Но это будет еще более многословно, чем при использовании Sys.Net.WebRequest напрямую.

Но есть и преимущество. SP.PageRequest обрабатывает RequestDigest, что поможет делать запросы к SharePoint.

Если вы не знаете, то в SharePoint  в post запросе к странице нельзя делать Update, если не передан корректный Request Digest. Аналогично нельзя обращаться к REST эндпоинту для изменения данных без RequestDigiest. Это должно защищать от CSRF атак.

Документация по SP.PageRequest - http://msdn.microsoft.com/en-us/library/ee547454(v=office.14).aspx

SP.WebProxy

Этот класс также находится в sp.js. В отличие от предыдущих, его предназначение – делать кросс-сайтовые запросы. К сожалению это доступно только для приложений, из обычного скрипта воспользоваться этим классом не получится.

Кстати он не менее многословен, чем Sys.Net.WebRequest, так что у вас и желания не будет его использовать для всего подряд.

var context = SP.ClientContext.get_current();
var request = new SP.WebRequestInfo();
request.set_url(
    "http://services.odata.org/Northwind/Northwind.svc/Categories"
    );
request.set_method("GET");

request.set_headers({ "Accept": "application/json;odata=verbose" });
var response = SP.WebProxy.invoke(context, request);
context.executeQueryAsync(successHandler, errorHandler);

function successHandler() {
    if (response.get_statusCode() == 200) {
        //Do stuff
    }
}

Но и это еще не все. Чтобы код выше заработал надо в манифест приложения вписать следующий элемент:

<RemoteEndpoints>
    <RemoteEndpoint Url=" http://services.odata.org" />
</RemoteEndpoints>

Подробно о применении класса SP.WebProxy по ссылке - http://msdn.microsoft.com/en-us/library/fp179895.aspx

SP.RequestExecutor

Этот класс находится в отдельном файле sp.requestexecutor.js, может работать как в SharePoint, так и вне его.

По-умолчанию на страницы SharePoint он не загружается и чтобы его использовать надо написать такой код:

SP.SOD.registerSod('sp.requestexecutor.js',
            '/_layout/15/sp.requestexecutor.js');
SP.SOD.executeFunc('sp.requestexecutor.js', 
            'SP.RequestExecutor', 
            function() {
                //Do stuff
            });

Если у вас html страница в SharePoint, то можете просто подключить скрипт на страницу и не использовать Script On Demand.

Использовать SP.RequestExecutor гораздо проще, чем предшествующие варианты:

var re = new SP.RequestExecutor(targetSiteUrl);
re.executeAsync({
    url: targetUrl,
    method: 'GET',
    success:function(response) {
        //console.log(response.body);
        //do stuff
    }
});

Также, как и SP.PageRequest, SP.RequestExecutor автоматически отправляет RequestDigiest. Так что руками передавать его, как написано во многих примерах, не обязательно.

SP.RequestExecutor может работать с бинарными данными, но из-за ошибки надо устраивать пляски с бубуном чтобы все заработало - http://techmikael.blogspot.ru/2013/07/how-to-copy-files-between-sites-using.html

В зависимости от того какой url вы передали в конструктор SP.RequestExecutor будет иметь разное поведение.

  • Если hostname в targerSiteUrl совпадает с hostname текущей страницы, то будут обычные ajax запросы.
  • Если не совпадает, то RequestExecutor будет пытаться отправлять запросы через AppProxy. Этот сценрий будет работать если у вас страница находится в SharePoint App.

Кроме того, можно передать вторы параметром в конструктор адрес хендлера, который использует класс Microsoft.SharePoint.Client.RequestForwarder (ни разу не видел чтобы им кто-либо пользовался). Это позволит обращаться к серверу SharePoint из javascript, расположенного на внешнем сайте и не использующем модель приложений. Ранее я про эту возможность писал в статье http://gandjustas.blogspot.com/2012/03/silverlight-sharepoint-2.html.

Кстати Microsoft.SharePoint.Client.RequestForwarder использует класс HttpContext, который создает ссылку на сборку System.Web. Из-за этого сборку Microsoft.SharePoint.Client нельзя использовать в Windows 8 приложениях.

Примеры SP.RequestExecutor по ссылке - http://msdn.microsoft.com/en-us/library/jj164022.aspx

SP.ProxyWebRequestExecutor и SP.ProxyWebRequestExecutorFactory

Эти два класса дополняют SP.RequestExecutor. SP.ProxyWebRequestExecutor является наследником Sys.Net.WebRequestExecutor и использует SP.RequestExecutor для выполнения запросов. Вы можете использовать его в любом коде, работающим с Sys.Net.WebRequest (интересно есть у вас такой), например чтобы заработало в Apps.

Класс SP.ProxyWebRequestExecutorFactory необходимо использовать если вы собираетесь использовать JSOM на не-SharePoint страницах.

var factory = new SP.ProxyWebRequestExecutorFactory(targetUrl);
var ctx = new SP.ClientContext(targetUrl);
ctx.set_webRequestExecutorFactory(factory);

Документации по этим классам нет, но в проект SPTypeScript я недавно залил дефинишены (описания типов) для всех полезных классов sp.requestexecutor.js  - http://sptypescript.codeplex.com/SourceControl/latest#Definitions/SP.RequestExecutor.d.ts
API небольшое и понять семантику несложно.

Рекомендации

Если вы делаете javascript для работы с SharePoint на страницах SharePoint, то используйте JSOM. Она достаточно мощная в 2013 и покрывает почти все сценарии. Для обращения к таким вещам как ExcelRest используйте SP.PageRequest.

Если вы делаете не-SharePoint, или в других сложных случаях, страницы используйте SP.RequestExecutor и JSOM с помощью SP.ProxyWebRequestExecutorFactory.

Если вас пугает многословный API для JSOM, то используйте TypeScript и дефинишены из проекта http://sptypescript.codeplex.com/, они почти полностью покрывают JSOM.

А как же jQuery?

В SharePoint 2013 почти не нужно. Ajax запросы можно делать и без нее, а для манипуляций с DOM есть библиотека mQuery. Про анимацию в SharePoint 2013 напишу в следующий раз.

Теги : ajax, js, sp2013, javascript, typescript, SharePoint