1

I am developing a Farm Solution (full trust) with some custom WebParts. For one WebPart i want some ajax behaviour, so i thought: Why not use the JSOM API? My web part just want to retrieve the new Announcements, so i added a new WebPart (Farm Solution), some HTML and the following javascript

<script src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js" type="text/javascript"></script>

<script type="text/javascript">

function retrieveListItems() {
  SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {
    var ctx = SP.ClientContext.get_current();
    var web = ctx.get_web();
    var list = web.get_lists().getByTitle("Announcements");
    ctx.load(list);
    ctx.executeQueryAsync(
          function () {
              console.log(list.get_title());
          },
          function (sender, args) {
              console.log(args.get_message());
          }
        );
  });
}

in my html i have a link to call the js function:

<a onclick="retrieveListItems(); return false;">Call</a>

When i call the function i receive an 403 FORBIDDEN error, the google chrome console shows me the following

/_vti_bin/client.svc/ProcessQuery 403 (FORBIDDEN)
     executeRequest         @ MicrosoftAjax.js:5
     executeRequest         @ MicrosoftAjax.js:5
     invoke                 @ MicrosoftAjax.js:5
     $31_0                  @ sp.runtime.js:2
     executeClientRequestAsync  @ sp.runtime.js:2
     executeQueryAsync      @ sp.runtime.js:2
     retrieveListItems      @ default.aspx:1091
     onclick                @ default.aspx:1118

And in the NETWORK tab of the Google Chrome console, in the PREVIEW (response) i see the following

[{SchemaVersion: "15.0.0.0", LibraryVersion: "15.0.4420.1017", ErrorInfo: {,…},…}]
  0:{SchemaVersion: "15.0.0.0", LibraryVersion: "15.0.4420.1017", ErrorInfo: {,…},…}
  ErrorInfo:{,…}
  ErrorCode:-2130575251
  ErrorMessage:"A validação de segurança para esta página não é válida e pode estar corrompida. Use o botão Voltar do navegador da Web para tentar realizar a operação novamente."
  TRANSLATING: The security validation for this page is invalid and might be corrupted.  Please use your web browser's Back button to try your operation again.
  ErrorTypeName:"Microsoft.SharePoint.SPException"
  ErrorValue:null
  TraceCorrelationId:"78edb09d-fb1d-7012-0000-026d47d0154a"
  LibraryVersion:"15.0.4420.1017"
  SchemaVersion:"15.0.0.0"
  TraceCorrelationId:"78edb09d-fb1d-7012-0000-026d47d0154a"

I do some research i found something related with FormDigest, so i searched my HTML markup for the __REQUESTDIGEST and copied its value, called the function and realized that the digest sent is different. It could be the source of the problem?

I do more research and found this js function that cheats the RequestDigest:

 function CustomUpdateFormDigest() {
    if (window._spPageContextInfo != null) {
        var $v_2 = window._spPageContextInfo;
        var $v_3 = $v_2.webServerRelativeUrl;
        var $v_4 = window._spFormDigestRefreshInterval;
        UpdateFormDigest($v_3, $v_4);
    }
}

Called it before call my retrieveListItems() function but it not worked. Anyone can point me to the right direction? it is really a digest problem?

EDIT: I realised that if my page has my web part i get the error when i click in the link AND if i execute the script in the google chrome console. If i remove my webpart from page, i can execute the script in Google Chrome Console succesfully.

Ewerton
  • 4,046
  • 4
  • 30
  • 56
  • I realised that If i call my function in the Google Chrome Console in my "Home Page" i get the forbidden error, but it i call it in the "Site Contents" page, it works – Ewerton Oct 26 '16 at 15:48

2 Answers2

1

You should not instanciate a new context if you're querying against the same site but instead use SP.ClientContext.get_current().
If you're querying another web then you'll have to handle some authentication and/or use the execution proxy depending on what you're doing. Keep in mind this is generally a bad practice to query to a different site. You should rather use search instead.
Also you should not reference SharePoint js files but use the Script On Demande (SOD) structure to wait for SharePoint to be ready before calling you're library.

baywet
  • 4,377
  • 4
  • 20
  • 49
  • Nice, will try a post back my results, can you provide me some samples or links on how to use the SOD you mentioned? – Ewerton Oct 26 '16 at 15:00
  • With the context thing I provided to you? Do you have any loading issue (http) ? Or any error in the console? – baywet Oct 26 '16 at 15:34
  • Yes, with the context you sugested me works, but works with my original code in the "Site Contents" page. And yes, there are some 404 for one image – Ewerton Oct 26 '16 at 15:40
  • Solved the 404 problems (no errors in the concole) but the issue persists – Ewerton Oct 26 '16 at 15:53
  • 1
    Ok so then it might be a problem of js loading sequence. Here is some good documentation about SOD http://www.ilovesharepoint.com/2010/08/sharepoint-scripts-on-demand-spsod.html when you're talking about other site is it the same or a different server/ web app/site collection? – baywet Oct 26 '16 at 19:55
  • you are right, i found the solution! Will answer here – Ewerton Oct 26 '16 at 20:00
1

Found the solution!

I was referencing my scripts in the wrong way I was referencing like this:

<script src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js" type="text/javascript"></script>
<script type="text/javascript" src="/_layouts/15/sp.runtime.js"> </script>
<script type="text/javascript" src="/_layouts/15/sp.js"> </script>
<script type="text/javascript" src="/_layouts/SP.debug.js"></script>

the correct way is:

<script src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js" type="text/javascript"></script>
<script type="text/javascript" src="/Style Library/Js/TopNavigation.js"> </script>

And load the SP scripts when i will use it, like this:

SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {
   // My code...
});
Ewerton
  • 4,046
  • 4
  • 30
  • 56