在跨境内容运营、海外营销场景中,获取文章在 Twitter、Facebook 等平台的分享传播数据是核心需求。尽管 Twitter 和 Facebook 官方接口普遍要求身份验证,但通过 JSONP(JSON with Padding)跨域技术,可绕开复杂的验证流程直接获取分享数量。本文将从原理到实操,详细讲解实现方法,并补充多平台适配、兼容性处理等实用知识点。
浏览器的同源策略会限制 AJAX 请求跨域资源,但<script>标签不受该策略约束 —— 这是 JSONP 的底层逻辑:
关键优势:无需配置 CORS、无需申请 API 密钥,轻量化实现跨域数据获取(仅适用于平台开放的无验证统计接口)。
Twitter 和 Facebook 要求身份验证来获取文章的数量,但事实证明你可以通过 JSONP 来获取这些信息,本文介绍如何使用一些简单的代码来获取并跳过验证这一步,请参考下面的步骤。
我将使用基本的 JavaScript 来告诉你如何做到这一点:
代码如下:
// 获取文章数量的封装对象
var socialGetter = (function() {
/* JSONP: 获取脚本的工具函数 */
function injectScript(url) {
var script = document.createElement('script');
script.async = true;
script.src = url;
document.body.appendChild(script);
}
return {
getFacebookCount: function(url, callbackName) {
injectScript('https://graph.facebook.com/?id=' + url + '&callback=' + callbackName);
},
getTwitterCount: function(url, callbackName) {
injectScript('http://urls.api.twitter.com/1/urls/count.json?url=' + url + '&callback=' + callbackName);
}
};
})();
// 回调方法
function twitterCallback(result) {
result.count && console.log('The count is: ', result.count);
}
function facebookCallback(result) {
result.shares && console.log('The count is: ', result.shares);
}
// 调用
socialGetter.getFacebookCount('http://davidwalsh.name/twitter-facebook-jsonp', 'facebookCallback');
socialGetter.getTwitterCount('http://davidwalsh.name/twitter-facebook-jsonp', 'twitterCallback');
因为有众多轻量级的 micro-frameworks 来处理 JSONP,所以本文最重要的部分可能是获取信息的 url 了。根据需要和习惯选择你的 JSONP 工具!Twitter 和 Facebook 对于这些请求肯定有数量和频率上的限制,所以如果你的网站访问量很大,则 JSONP 很可能会被拦截或屏蔽。
以下接口均为各平台公开的无验证统计接口,返回格式以 JSON 为主(部分含特殊包装),可直接适配 JSONP 调用,是跨境内容数据统计的核心资源。
GET URL:
http://cdn.api.twitter.com/1/urls/count.JSon?url=http://stylehatch.co
返回结果:
{
"count":528,
"url":"http://stylehatch.co/"
}
GET URL:
http://graph.facebook.com/?id=http://stylehatch.co
返回结果:
{
"id": "http://stylehatch.co",
"shares": 61
}
GET URL:
http://api.pinterest.com/v1/urls/count.json?callback=&url=http://stylehatch.co
返回结果:
({"count": 0, "url": "http://stylehatch.co"})
补充:返回数据被括号包裹,需在回调函数中额外处理(如result = JSON.parse(result.replace(/^\(|\)$/g, '')))。
GET URL:
http://www.linkedin.com/countserv/count/share?url=http://stylehatch.co&format=json
返回结果:
{
"count":17,
"fCnt":"17",
"fCntPlusOne":"18",
"url":"http:\/\/stylehatch.co"
}
补充:Google Plus 无公开 JSONP 接口,需 POST 请求 + API Key 调用,不支持跨域直接访问
POST URL:
https://clients6.google.com/rpc?key=YOUR_API_KEY
POST body:
[{
"method":"pos.plusones.get",
"id":"p",
"params":{
"nolog":true,
"id":"http://stylehatch.co/",
"source":"widget",
"userId":"@viewer",
"groupId":"@self"
},
"jsonrpc":"2.0",
"key":"p",
"apiVersion":"v1"
}]
返回结果:
[{
"result": {
"kind": "pos#plusones",
"id": "http://stylehatch.co/",
"isSetByViewer": false,
"metadata": {
"type": "URL",
"globalCounts": {
"count": 3097.0
}
}
} ,
"id": "p"
}]
GET URL:
http://www.stumbleupon.com/services/1.01/badge.getinfo?url=http://stylehatch.co
返回结果:
{
"result":{
"url":"http:\/\/stylehatch.co\/",
"in_index":true,
"publicid":"1iOLcK",
"views":39,
"title":"Style Hatch - Hand Crafted Digital Goods",
"thumbnail":"http:\/\/cdn.stumble-upon.com\/mthumb\/941\/72725941.jpg",
"thumbnail_b":"http:\/\/cdn.stumble-upon.com\/bthumb\/941\/72725941.jpg",
"submit_link":"http:\/\/www.stumbleupon.com\/submit\/?url=http:\/\/stylehatch.co\/",
"badge_link":"http:\/\/www.stumbleupon.com\/badge\/?url=http:\/\/stylehatch.co\/",
"info_link":"http:\/\/www.stumbleupon.com\/url\/stylehatch.co\/"
},
"timestamp":1336520555,
"success":true
}
将代码进行封装,我们将上面 Facebook,Twitter,LinkedIn 三个社交网站的 API 进行封装,以方便页面调用。
$.fn.getShareCount = function (url) {
var self = this;
var displayShareCount = function (val, obj) {
if (!isNaN(val) && val > 0) {
obj.show();
if (val > 999) {
obj.attr("title", val);
obj.text("500+");
}
else
obj.text(val);
}
};
return {
facebook: function () {
$.get("http://api.facebook.com/method/links.getStats?urls=" + url, function (d) {
var c = $(d).find("total_count").text();
self.each(function () { displayShareCount(c, $(this)); });
});
},
twitter: function () {
$.getJSON("http://cdn.api.twitter.com/1/urls/count.json?url=" + url + "&callback=?", function (d) {
self.each(function () { displayShareCount(d.count, $(this)); });
});
},
linkedin: function () {
$.getJSON("http://www.linkedin.com/countserv/count/share?url=" + url + "&callback=?", function (d) {
self.each(function () { displayShareCount(d.count, $(this)); });
});
}
};
};
然后在页面上这样调用:
$(function () {
var shareUrl = window.location.href.toLowerCase();
$('#fackbook_count').getShareCount(shareUrl).facebook();
$('#twitter_count').getShareCount(shareUrl).twitter();
$('#linkedin_count').getShareCount(shareUrl).linkedin();
});
正在加载... ...