Как вы думаете, сколько способов сделать 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 напишу в следующий раз.