Problem running GetListItems in a webpart

Oct 16, 2013 at 3:24 PM
Moving this from issues to discusssions:


I successfully ran SPServices (latest) from a blank web page in SP 2010 and was able to query a list on the same server.
Here's what it looks like:
<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
  <script type="text/javascript" src="/jQueryLibraries/jquery-1.10.2.js"></script>
  <script type="text/javascript" src="/jQueryLibraries/jquery-ui.min.js"></script>
  <script type="text/javascript" src="/jQueryLibraries/jquery.SPServices-2013.01.js"></script>
</asp:Content>


<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">

  <script>
      var itemSource = [];
      var itemHash = {}; // new object
      var k = 0;

      $(document).ready(function () {
          $().SPServices({
              operation: "GetListItems",
              async: false,
              listName: "Applications",
              CAMLViewFields: "<ViewFields><FieldRef Name='txtLastName' /><FieldRef Name='txtFirstName' /><FieldRef Name='ID' /></ViewFields>",
              completefunc: function (xData, Status) {
                  $(xData.responseXML).SPFilterNode("z:row").each(function () {
                      itemSource[k] = $(this).attr("ows_txtLastName") + ', ' + $(this).attr("ows_txtFirstName");
                      itemHash[itemSource[k]] = $(this).attr("ows_ID");
                      k = k + 1;
                  });
              }
          });

      });
  </script>
  <label for="studentname">Student Name: </label>
  <input id="studentname" style="width:200" /><input id="studentdetailsbutton" type="button" value="Details &gt;&gt;" />

  <script>
      $("#studentname").autocomplete({
          source: itemSource
      });

      $('#studentdetailsbutton').click(function () {
          var studentName = $('#studentname').val();
          var studentId = itemHash[studentName];

          if (studentId != undefined) {
              var options = {
                  title: 'Applications: ' + studentName,
                  url: "/Lists/Applications/MyApplications/editifs.aspx?ID=" + studentId + "&List=xxxxxxxxxxxx&Web=yyyyyyyyyyyy"
              };
              SP.UI.ModalDialog.showModalDialog(options);
          }
      });
      
      </script>
</asp:Content>
Next, I took the same code and put it into a web part. I injected the libraries onto the page using the ClientScriptManager.
However, SPServices doesn't behave the same way, specifically this line of code inside of SPServices (line 3776):
if(typeof _spPageContextInfo !== "undefined") {
Is not longer undefined and the .webServerRelativeUrl is "/".
This leads to a problem - when the ajax code tries to do a call, it compares the domains and thinks it's cross side scripting - it's not though - it's just that SPServices didn't put in the full domain name.
This does not appear to be a problem with jquery, instead it looks like an issue with SPServices and the use of _spPageContextInfo.

I "fixed" the issue by simply commenting out the SP2010 specific code and forcing it to use the SP2007 code. That correctly sets the site and the ajax call works fine because the call and the site are both in the same domain.


I tried to reproduce the isse by simply modifying my original code and moving the line:
   <script type="text/javascript" src="/jQueryLibraries/jquery.SPServices-2013.01.js"></script>
into the ContentPlaceHolderID="PlaceHolderMain" section, and poof, it breaks due to the same issue. When tracing through the code, i found that the original code works fine because _spPageContextInfo is undefined, but moving it into the page populates the object and SPServices gets messed up.

Thanks.
Coordinator
Oct 16, 2013 at 3:28 PM
Now that I see a bit more of your code, my guess is that its something to do with sequencing. It may be that _spPageContextInfo is not defined yet.

M.
Oct 16, 2013 at 3:34 PM
What should be in the .webServerRelativeUrl property? Should it have the domain name?
Coordinator
Oct 16, 2013 at 3:50 PM
No, it should have the relative URL of the site (Web), like /sitename.

M.
Oct 16, 2013 at 3:55 PM
If it doesn't have the domain name and the ajax call DOES have the domain name, then jquery will abort with a cross-site scripting error. Not sure how this is supposed to work if the domain name doesn't get populated. Am i missing something?
Coordinator
Oct 16, 2013 at 4:00 PM
I build the URL like so, so yes it's a full URL.
        // Build the URL for the Ajax call based on which operation we're calling
        // If the webURL has been provided, then use it, else use the current site
        var ajaxURL = "_vti_bin/" + WSops[opt.operation][0] + ".asmx";
        if(opt.webURL.charAt(opt.webURL.length - 1) === SLASH) {
            ajaxURL = opt.webURL + ajaxURL;
        } else if(opt.webURL.length > 0) {
            ajaxURL = opt.webURL + SLASH + ajaxURL;
        } else {
            var currentSite = $().SPServices.SPGetCurrentSite();
            ajaxURL = currentSite + (currentSite !== SLASH ? SLASH : "") + ajaxURL;
M.
Oct 16, 2013 at 4:13 PM
I saw that... problem is, opt.WebURL == "", so the URL gets built without a domain...
Coordinator
Oct 16, 2013 at 4:20 PM
Is it possible that SPServices is loading before SharePoint's script files? That could mean that _spPageContextInfo would exist, but not yet have any values.

M.
Oct 16, 2013 at 7:30 PM
Edited Oct 16, 2013 at 7:30 PM
No, i don't believe so. I just built a brand new web application, created a new site collection, added the jquery and spservices files to a new dcoument library. Then i created a new page and put the web part on the page. I stepped into the javascript debugger and found the exact same behavior - the ajaxURL has no server name, it looks like:
ajaxURL "//_vti_bin/Lists.asmx" String
Examining the _spPageContextInfo reveals:
[-]     _spPageContextInfo  {...}   Object
        siteServerRelativeUrl   "/" String
        userId  1   Number
        webLanguage 1033    Number
        webServerRelativeUrl    "/" String
        webUIVersion    4   Number
It's populated and looks as it should. And as i stated above, opt.weburl is empty, only the GetListItems options are popluated.
Oct 17, 2013 at 12:54 AM
Marc, this feels like this issue:


No?

From the script references above, looks like a version earlier than 2013.02ALPHA3 is being used, which is where this issue was fixed.

Paul


--

_________
Paul T

Coordinator
Oct 17, 2013 at 1:33 AM
Could be. I have two threads going with similar issues, and I thought I recommended trying 2013.02ALPHA3 here, but I didn't.

Can you give the alpha a go, jdcipher? If it doesn't work, try 0.7.2.

M.
Oct 17, 2013 at 1:39 AM
I just tried 2013.02ALPHA3, - no luck. I did notice that the AjaxURL is now single slash - but same issue exists in that there's no domain name, so jquery thinks it's cross-site scripting..
Oct 17, 2013 at 1:46 AM
Just tried 0.7.2 and it works fine.