facebook javascript API 中的分页如何工作?

IT技术 javascript facebook facebook-graph-api pagination
2021-03-18 19:29:15

我正在尝试使用 javascript sdk 在我的 facebook 新闻提要中恢复上周的帖子。我能够获得第一页,但是,我不知道如何继续遍历其他页面。我已经用下面的代码试过了:

 $('#loadPosts').bind('click', function() {     
            FB.api('/me/home',{since:'last week'}, getPosts);   
          });

 getPosts = function(response){
        for (element in response.data){
            post = response.data[element]
            console.log(post);          
          }

          previousPage = response.paging.previous;        
          console.log(previousPage);

          // can i call FB.api(previousPage, getPosts); ??      

      }

但是我得到一个 URL 作为上一页,我不知道如何从该 URL 进行 javascript FB.api 调用。有任何想法吗?

5个回答

好吧,对于一个简单的问题似乎有很多抱怨,我仍然相信我的旧答案可以澄清。无论如何,让我照顾你。:)

第一:我发现您无法从第一页真正转到“上一个”页面。理想情况下,我应该。所以,这是我提交的一个错误,你可能想要关注:https : //developers.facebook.com/bugs/391562790938294?browse=search_50fcac3ce094e7068176315

第二:如果这是由设计,你不能从第一页就又回到“以前”(因为以前没有),但是你一定能够进入“下一步”。但是,由于 API 表现为游标,并且您已经向前移动,现在您的“上一个”页面可以工作了。

问题的答案:
我得到一个 URL 作为上一页,但我不知道如何从该 URL 进行 javascript FB.api 调用。有任何想法吗?

是的,您可以进行 FB.api 调用。但我建议您改为进行 HTTP GET 调用,因为它更容易。另外,请注意,前一个可能会返回和空数组,如{"data":[]}

如何获取上一页/下一页?
在这里,我正在编写一个使用 jQuery 的小代码。如果您不想阅读代码,有两种方法:

  1. 使用上一个/下一个 URL 并发出 HTTP GET 请求。其中,如果不为空,将带有下一组“上一个”、“下一个”链接。
  2. 解析 URL,并以 JSON 的形式获取查询字符串并将其传递给FB.api. 我使用jQuery BBQ 插件进行解析。

重要说明:在示例中,我使用“下一个”URL,因为在第一个请求中,如果我使用“上一个”,它会给出空的 JSON,而不是给出过去的帖子。但是,一旦我向前移动了几页,我就可以使用“上一个”URL。与 Google 结果一样,您不能在第 1 页上转到上一页,但可以从任何 > 1 页(参见下面的示例 3)。这称为分页。

示例 1:使用 HTTP GET 的代码(首选):(我将加载 3 个帖子/页面并查看三个下一页)

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" src="https://raw.github.com/cowboy/jquery-bbq/master/jquery.ba-bbq.min.js"></script>
<script>

var i =0;
var getPosts = function (response){
          for (element in response.data){
            post = response.data[element]
            console.log(post.id + ": " +post.message);          
          }



          // can i call FB.api(nextPage, getPosts); ??
          if(i < 2){
              nextPage = response.paging.next;        
              console.log(nextPage);
              i++;
              //Method 1: I use it.
              $.get(nextPage, getPosts, "json"); //optional: $.getJSON can be use instead
          }

      }

$(document).ready(function(){

$('#loadPosts').bind('click', function() {
            FB.api('/me/home',{since:'yesterday','limit': '3'}, getPosts);   
          });
})
</script>
</head>
<body>
<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    // init the FB JS SDK
    FB.init({
      appId      : 'XXXXXXXXXXXX', // FILL YOUR APP ID HERE!
      status     : true, // check the login status upon init?
      cookie     : true, // set sessions cookies to allow your server to access the session?
    });

    // Additional initialization code such as adding Event Listeners goes here

  };
</script>
<button id="loadPosts">Load Posts</button>
<p>Please open developer console to see what's happening. In Firefox, you can use ctrl+shift+k, and in Chrome/Chromium use ctrl+shift+i</p>
</body>
</html>

回应

100004192352945_156620584487686: undefined
137723270230_10152423499430231: On this day, please spare a thought for those fellow citizens, for whom I just spare a thought and do nothing else.
642965867_10151211036740868: Thanks everyone for their wishes! The wishes made my day!

https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD&until=1359184568
367116489976035_536776529676696: Rage. Quit. Life.
899605553_10152450871820554: undefined
367116489976035_417820828298092: undefined

https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD&until=1359179890
137723270230_10152423148745231: Pratibha Patil used to love the Republic Day Parade, especially the part where the visiting Chief Guest extended her an invitation to visit his/her own country.
137723270230_10152423131700231: The Kingfisher tableau at Republic Day Parade was so simple. Vijay Mallya riding a bicycle.
367116489976035_484460034950769: undefined

示例 2:使用 FB.api 的代码:(我将加载 3 个帖子/页面并查看三个下一页)

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" src="https://raw.github.com/cowboy/jquery-bbq/master/jquery.ba-bbq.min.js"></script>
<script>

var i =0;
var getPosts = function (response){
          for (element in response.data){
            post = response.data[element]
            console.log(post.id + ": " +post.message);          
          }



          // can i call FB.api(nextPage, getPosts); ??
          if(i < 2){
              nextPage = response.paging.next;        
              console.log(nextPage);
              i++;

              //Method 2: If you have to call FB.api
              var params = jQuery.deparam.querystring(nextPage);
              console.log(JSON.stringify(params, null, 2));
              FB.api('/me/home', params, getPosts)
          }

      }

$(document).ready(function(){

$('#loadPosts').bind('click', function() {
            FB.api('/me/home',{since:'yesterday','limit': '3'}, getPosts);   
          });
})
</script>
</head>
<body>
<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    // init the FB JS SDK
    FB.init({
      appId      : 'XXXXXXXXXXXX', // FILL YOUR APP ID HERE!
      status     : true, // check the login status upon init?
      cookie     : true, // set sessions cookies to allow your server to access the session?
    });

    // Additional initialization code such as adding Event Listeners goes here

  };
</script>
<button id="loadPosts">Load Posts</button>
<p>Please open developer console to see what's happening. In Firefox, you can use ctrl+shift+k, and in Chrome/Chromium use ctrl+shift+i</p>
</body>
</html>

回应

367116489976035_536776529676696: Rage. Quit. Life.
899605553_10152450871820554: undefined
367116489976035_417820828298092: undefined
{
  "limit": "3",
  "access_token": "AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD",
  "until": "1359179890"
}

137723270230_10152423148745231: Pratibha Patil used to love the Republic Day Parade, especially the part where the visiting Chief Guest extended her an invitation to visit his/her own country.
137723270230_10152423131700231: The Kingfisher tableau at Republic Day Parade was so simple. Vijay Mallya riding a bicycle.
367116489976035_484460034950769: undefined

https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD&until=1359178140
{
  "limit": "3",
  "access_token": "AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD",
  "until": "1359178140"
}
655515199_403590309726450: a good resolution to take on Republic Day
505588854_496901583686790: Love the secret world that slow motion reveals.
693811975_10151217837201976: undefined

示例3:执行:page1 -> page2 -> page1 or page -> next -> previous下面的代码将加载page1,然后转到“next”页面(page2),然后回到page1,使用“previous”

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" src="https://raw.github.com/cowboy/jquery-bbq/master/jquery.ba-bbq.min.js"></script>
<script>

var i =0;
var getPosts = function (response){
          for (element in response.data){
            post = response.data[element]
            console.log(post.id + ": " +post.message);          
          }



          // can i call FB.api(nextPage, getPosts); ??
          if(i < 2){
              nextPage = response.paging.next;        
              if(i==1)
                nextPage = response.paging.previous;

              console.log(nextPage);
              i++;
              $.get(nextPage, getPosts, "json"); //optional: $.getJSON can be use instead
          }

      }

$(document).ready(function(){

$('#loadPosts').bind('click', function() {
            FB.api('/me/home',{since:'yesterday','limit': '3'}, getPosts);   
          });
})
</script>
</head>
<body>
<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    // init the FB JS SDK
    FB.init({
      appId      : 'XXXXXXXXXXXX', // FILL YOUR APP ID HERE!
      status     : true, // check the login status upon init?
      cookie     : true, // set sessions cookies to allow your server to access the session?
    });

    // Additional initialization code such as adding Event Listeners goes here

  };
</script>
<button id="loadPosts">Load Posts</button>
<p>Please open developer console to see what's happening. In Firefox, you can use ctrl+shift+k, and in Chrome/Chromium use ctrl+shift+i</p>
</body>
</html>

回应

PAGE1:
367116489976035_536806916340324: How big is the Solar System?
Full infographic here: http://bit.ly/WmzfVn
137723270230_10152423534790231: "Sociologist" Ashis Nandy has claimed that most of the corrupt came from OBC/SC/ST castes.
Following this, Corrupt people have strongly condemned Nandy's attempts to divide them on caste lines. They'll be united in loot, forever.
100004192352945_156620584487686: undefined

PAGE2:
https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAKqIMyCVYjH9upK4e2bjUwLoVbbFDL0ffc0SZBTVR9MUFGV4ZCq6HBdFIadFMpLDC3ATMZCJ4GPsXWpG4qTGODavuvzLAZDZD&until=1359185659

137723270230_10152423499430231: On this day, please spare a thought for those fellow citizens, for whom I just spare a thought and do nothing else.
642965867_10151211036740868: Thanks everyone for their wishes! The wishes made my day!
367116489976035_536776529676696: Rage. Quit. Life.

PAGE1:
https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAKqIMyCVYjH9upK4e2bjUwLoVbbFDL0ffc0SZBTVR9MUFGV4ZCq6HBdFIadFMpLDC3ATMZCJ4GPsXWpG4qTGODavuvzLAZDZD&since=1359185123&__previous=1

367116489976035_536806916340324: How big is the Solar System?
Full infographic here: http://bit.ly/WmzfVn
137723270230_10152423534790231: "Sociologist" Ashis Nandy has claimed that most of the corrupt came from OBC/SC/ST castes.
Following this, Corrupt people have strongly condemned Nandy's attempts to divide them on caste lines. They'll be united in loot, forever.
100004192352945_156620584487686: undefined

旧答案

使用limitoffsetsinceuntil参数,以实现自己的目标。

参考:http : //developers.facebook.com/docs/reference/api/

分页

查询连接时,有几个有用的参数使您能够过滤和分页连接数据:

以下应该获取所有帖子,last week直到yesterday21st - 30th消息开始(基本上,每页分页 10 条消息的第三页)。

 FB.api(
  '/me/home',
  {
    'since':'last week',
    'limit': '10',
    'offset': '20',
    'until': 'yesterday'
  }, 
  getPosts
); 

我刚刚测试过,它有效。我使用了 limit=4,这是页面大小的东西。因此,当我从 2011 年 2 月 2 日(Unix 时间戳:1296626400)到今天使用它获取数据时

https://graph.facebook.com/me/home?access_token=[AUTH_TOKEN]&since=1296626400&limit=4

它返回数据,此外它还返回 URL 以转到下一页

{
   "data": [
      <ARRAY OF POSTS HERE>
   ],
   "paging": {
      "previous": "https://graph.facebook.com/me/home?access_token=[NEW_AUTH_TOKEN]&since=1298026753&limit=4",
      "next": "https://graph.facebook.com/me/home?access_token=[NEW_AUTH_TOKEN]&limit=4&until=1298023222"
   }
}

您可以安全地使用JSON 对象的previousnext属性跳转到下一页(或上一页)。这似乎是最简单的方法。

顺便说一句,\u00257C需要转换为|使其工作。

@Nishant Facebook的只是有一个更新,我们不能使用limitoffset任何更长的时间,尝试sinceuntil替代
2021-04-22 19:29:15
@BangDao developer.facebook.com/docs/reference/api/pagination显示了三种类型的分页。我已经验证您可以使用limit基于游标的分页。此外,医生说他们也支持offset我会检查的。我不希望他们有过时的文档。
2021-04-23 19:29:15
我从谷歌来到这里,这个答案没有回答我的问题
2021-04-25 19:29:15
那些带着同样问题从 Google 来到这里的人呢?与问题不匹配的答案没有长期value。
2021-05-02 19:29:15
我想你没有回答海报问题。他说:“但我得到的 URL 是前一页,我不知道如何从该 URL 进行 javascript FB.api 调用”。
2021-05-08 19:29:15

如果您只是想获取下一页(使用 paging.next 对象),您可以执行 jQuery.getJSON 请求。类似于以下内容:

function loadAlbums(){
    FB.api('/me/albums', function(response){
        handleAlbumsResponse(response);
    });
}

function handleAlbumsResponse(response){
    var albums = response.data;

    for( var i in albums){
        var album = albums[i];
        $('#albums ul').append('<li><a href="#">' + album.name + '</a></li>');
    }

    if( response.paging.next){
        console.log('fetching next page...');
        $.getJSON(response.paging.next, function(response){                
            handleAlbumsResponse(response);
        });
    } 
} 

您问题中的关键限制是我们不能使用响应中提供的“下一个”网址。

我将尝试通过首先提出一个更一般的问题来回答您的问题:

我们如何为我们的 Facebook 应用创造一种用户体验,让每次调用更多项目返回相同数量的项目。

如果用户请求“更多”并获得 10 个项目,按“更多”并获得 4、7 等,她可能认为我们的应用程序有问题。

在 Open Graph介绍页面上介绍了用于分页的不同参数。这些是:

限制

抵消

直到

自从

如“分页”标题下所述。但是,如果我们实现了一个带有限制和偏移的解决方案,我们增加了 offset ,例如:

https://graph.facebook.com/me/home?limit=10&offset=OFFSET

其中 OFFSET 会增加每个请求的限制,我们发现返回的结果数量有时会不等于我们指定的“限制”参数。这是因为检查查询结果是否对查看者可见之前,参数已应用于 Facebook 端我们要求 10 件,但我们可能会得到 8 件作为回报。

这意味着如果我们希望我们的应用程序的“更多”请求始终返回相同数量的项目,我们就不能使用增加限制和偏移量的解决方案。

Jeff Bowen(在 Facebook 平台团队工作)在这篇博客中提出的解决方案是这样的逻辑:

  • 请求项目的限制 = YOUR_LIMIT。
  • 检索响应中最后一项的 created_time 字段。
  • 请求接下来的 10 个项目,因为 = RETRIEVED_CREATED_TIME 和 limit=YOUR_LIMIT

这是一个代码示例,基于上述博客文章中的示例:

var graphURL = "https://graph.facebook.com/me/home?" +
                 "callback=processResult&" +
                 "date_format=U&" +
                 "limit=10";

function loadPosts() {
  var script = document.createElement("script");
  script.src = graphURL;
  document.body.appendChild(script);
}

function processResult(posts) {
  if (posts.data.length == 0) {
    document.getElementById("loadMore").innerHTML =
      "No more results";
  }
  else {
    graphURL = graphURL + "&until=" +
      posts.data[posts.data.length-1].created_time;

    for (var post in posts.data) {
      var message = document.createElement("div");
      message.innerHTML = posts.data[post].message;
      document.getElementById("content").appendChild(message);
    }
  }
}
    

此解决方案按时间顺序从用户的新闻源中检索接下来的 10 个项目,而不使用 JSON 响应中的 url。

这很好奇。建议您将其作为新问题与您的代码一起发布。
2021-04-20 19:29:15
在使用相同的逻辑创建了类似的代码之后,我遇到了这篇文章。然而,当我调用这个函数时,帖子的数量会减少(几乎正好减半),直到它达到零。你见过这种行为吗?
2021-05-02 19:29:15
终于把问题贴出来了。
2021-05-02 19:29:15

它正在工作

    function friends_list()
    {

        for (var x = 0; x<500; x++)
        {
            FB.api(
            '/me/friendlists/',
            'GET',
            {"fields":"id","offset":x},
            function(response) {
            for (i = 0; i < response.data.length; i++) 
            { 

            document.getElementById("friends_list").innerHTML =  
            document.getElementById("friends_list").innerHTML + "<br>" + response.data[i].id; 

            }
            document.getElementById("friends_list").innerHTML =  
            document.getElementById("friends_list").innerHTML + "<br>" ;
            }
            );
        }


    }

我注意到这个问题很老了。这几天我的回答是真实的 FB jsSDK (2017) :)

实际上它比前辈描述的更简单,并且有点直观。FB jsSDK 它本身就是一个 API,它应该能够自己浏览响应页面并使用相同的方法,不是吗?

function getPosts(){
    FB.api('/me/posts', 'GET', {limit:250}, cbGetPosts);
}

function cbGetPosts(response){
    // do your stuff with response.data
    if(response && response.paging){
     FB.api(response.paging.next, cbGetPosts); // yep, is this simple
    }
}

显然,只要定义了下一个键但证明了该概念,这将请求下一页。

为死灵感到抱歉,但您知道是否有可能的方法来做类似的事情。我正在尝试获取我的数据的第二页,它永远不会出现
2021-05-08 19:29:15