Thực hiện chia sẻ đa nền tảng trên web di động

Khi các ứng dụng di động thường có tính năng chia sẻ lên các nền tảng mạng xã hội, thì các trang web cũng có nhiều framework hỗ trợ chia sẻ tốt. Tuy nhiên, với sự phát triển không ngừng của HTML5, ngày càng nhiều trang web di động xuất hiện trong cuộc sống hàng ngày. Vậy làm thế nào để thực hiện chia sẻ trên thiết bị di động? Các nền tảng chia sẻ đều cung cấp SDK cho Android và iOS, và như một nhà phát triển, chúng ta chỉ cần tích hợp SDK vào dự án của mình. Qua các giao diện được cung cấp, việc thực hiện chức năng chia sẻ trở nên dễ dàng. Đối với các trang web, cũng tồn tại nhiều framework chia sẻ tuyệt vời trên mạng như: bShare, JiaThis. Chúng ta có thể dễ dàng tích hợp chúng vào dự án. Tuy nhiên, để thực hiện chia sẻ trên trang web di động, chúng ta cần thêm một chút nỗ lực vì lúc này chúng ta có thể gọi ứng dụng đã cài đặt của người dùng để chia sẻ. Đặc biệt cần nhắc đến chia sẻ WeChat. Trên trang web, khi chia sẻ, chúng ta thường hiển thị mã QR, người dùng quét bằng ứng dụng WeChat để chia sẻ. Trong môi trường di động, chúng ta không thể làm như vậy, mà cần mở trực tiếp ứng dụng khi người dùng chọn chia sẻ WeChat. Cần nói thêm về SDK JS của WeChat, khi lần đầu tiếp xúc với nó, tôi tưởng chỉ cần thực hiện đúng thao tác là có thể tùy chỉnh chia sẻ, nhưng sau nhiều lỗi, cuối cùng nhận ra rằng SDK JS của WeChat chỉ lưu tạm nội dung tùy chỉnh, khi cần chia sẻ vẫn phải sử dụng nút chia sẻ ở góc trên bên phải.

Phương pháp chia sẻ qua liên kết siêu văn bản

Đối với các nền tảng mạng xã hội phổ biến, chúng ta có thể chia sẻ nội dung thông qua liên kết siêu văn bản, ngoại trừ WeChat. Phương pháp này cho phép tùy chỉnh chia sẻ một cách thuận tiện.

function shareToSina() {
    // Chia sẻ lên Weibo
    var sinaUrl = 'http://service.weibo.com/share/share.php?title=' + $("#title").val() + '&url=' + $("#url").val();
    window.location.href = sinaUrl;
}

function shareToQQZone(){
    var params = {
        url: location.href,
        showcount: '0',
        desc: '',
        summary: '',
        title: '',
        site: 'ManYi',
        pics: '',
        style: '203',
        width: 98,
        height: 22
    };
    // Chia sẻ lên QQ Zone
    var qqzoneUrl = 'http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?title=' + $("#title").val() + '&url=' + $("#url").val() + '&site="ManYi"';
    window.location.href = qqzoneUrl;
}

function shareToQQ() {
    var params = {
        url: location.href,
        desc: '',
        title: '',
        summary: '',
        pics: '',
        flash: '',
        site: 'ManYi',
        style: '201',
        width: 32,
        height: 32
    };
    // Chia sẻ lên QQ
    var qqUrl = 'http://connect.qq.com/widget/shareqq/index.html?title=' + $("#title").val() + '&summary=' + $("#url").val() + '&url=' + $("#url").val() + '&site="ManYi"';
    window.location.href = qqUrl;
}

function shareToTencentWeibo() {
    var params = {
        url: location.href,
        title: '',
        pic: '',
        site: 'ManYi'
    };
    // Chia sẻ lên Tencent Weibo
    var weiboUrl = 'http://v.t.qq.com/share/share.php?title=' + $("#title").val() + '&url=' + $("#url").val() + '&site="ManYi"';
    window.location.href = weiboUrl;
}

Mã JavaScript trên giúp thực hiện chia sẻ lên Weibo, QQ, QQ Zone và Tencent Weibo. Chỉ cần gọi các hàm này tại vị trí mong muốn trên trang.

Chia sẻ WeChat

Trình duyệt trong WeChat có nút chia sẻ ở góc trên bên phải, điều này khiến việc chia sẻ trực tiếp lên dòng thời gian WeChat trên trang web trở nên khó khăn. WeChat cung cấp SDK JS để tùy chỉnh chia sẻ. Dưới đây là cách thực hiện:

Bước 1: Lấy access_token

access_token là mã xác thực duy nhất cho tất cả các API của nhóm công cộng. Mã này cần được lưu trữ cẩn thận. Thời hạn hiệu lực là 2 giờ, cần cập nhật định kỳ.

Bước 2: Lấy jsapi_ticket

jsapi_ticket là mã tạm thời dùng để gọi API WeChat JS. Thời hạn hiệu lực là 7200 giây, lấy từ access_token. Do số lần gọi API này rất giới hạn, nên cần lưu trữ toàn cục jsapi_ticket.

Bước 3: Sinh chữ ký xác thực JS-SDK

Quy tắc sinh chữ ký bao gồm các tham số: noncestr (chuỗi ngẫu nhiên), jsapi_ticket, timestamp (thời gian), url (đường dẫn trang hiện tại, không bao gồm phần sau #). Sắp xếp các tham số theo thứ tự bảng chữ cái, nối thành chuỗi, rồi mã hóa SHA1.

Triển khai mã C#

using System;
using System.Net;
using System.Web.Mvc;
using System.IO;
using System.Text;
using System.Web.Script.Serialization;
using ManYiAbyWAP.Models;

namespace ManYiAbyWAP.Controllers
{
    public class WXMessageController : Controller
    {
        private static string APPID = "appid được cung cấp bởi WeChat";
        private static string SECRECT = "secrect được cung cấp bởi WeChat";
        public static WXInfo accessToken = null;
        public static DateTime overTime = DateTime.Now;

        public ActionResult GetToken(string url) {
            if (accessToken != null)
            {
                TimeSpan span = Convert.ToDateTime(overTime).Subtract(Convert.ToDateTime(DateTime.Now));
                if (span.TotalHours > 2)
                {
                    accessToken = GETWinXinToken();
                    overTime = DateTime.Now;
                }
            }
            else
            {
                accessToken = GETWinXinToken();
                overTime = DateTime.Now;
            }

            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            accessToken.timestamp = Convert.ToInt64(ts.TotalSeconds).ToString();
            accessToken.noncestr = createNonceStr(16);

            string str = "jsapi_ticket="+ accessToken.ticket+ "&noncestr="+ accessToken.noncestr + "×tamp="+ accessToken.timestamp + "&url="+ url;
            accessToken.signature = SHA1(str).ToLower();
            accessToken.APPID = APPID;
            return Json(accessToken, JsonRequestBehavior.AllowGet);
        }

        private string createNonceStr(int length = 16)
        {
            string str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            Random r = new Random();
            string result = string.Empty;
            for (int i = 0; i < length; i++)
            {
                int m = r.Next(0, 62);
                string s = str.Substring(m, 1);
                result += s;
            }
            return result;
        }

        private static string SHA1(string text)
        {
            byte[] cleanBytes = Encoding.Default.GetBytes(text);
            byte[] hashedBytes = System.Security.Cryptography.SHA1.Create().ComputeHash(cleanBytes);
            return BitConverter.ToString(hashedBytes).Replace("-", "");
        }

        private static WXInfo GETWinXinToken() {
            HttpWebResponse response = CreateGetHttpResponse("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret=" + SECRECT, 5000);
            StreamReader reader = new StreamReader(response.GetResponseStream());
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = reader.ReadLine()) != null)
            {
                sb.Append(line.ToString());
            }

            JavaScriptSerializer js = new JavaScriptSerializer();
            WXInfo accessToken = js.Deserialize<WXInfo>(sb.ToString());

            response = CreateGetHttpResponse("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken.access_token + "&type=jsapi", 5000);
            reader = new StreamReader(response.GetResponseStream());
            sb = new StringBuilder();
            while ((line = reader.ReadLine()) != null)
            {
                sb.Append(line.ToString());
            }
            accessToken = js.Deserialize<WXInfo>(sb.ToString());
            return accessToken;
        }

        public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent=null, CookieCollection cookies=null)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("url");
            }
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "GET";
            if (!string.IsNullOrEmpty(userAgent))
            {
                request.UserAgent = userAgent;
            }
            if (timeout.HasValue)
            {
                request.Timeout = timeout.Value;
            }
            if (cookies != null)
            {
                request.CookieContainer = new CookieContainer();
                request.CookieContainer.Add(cookies);
            }
            return request.GetResponse() as HttpWebResponse;
        }
    }
}

Lớp WXInfo.cs chứa thông tin token:

namespace ManYiAbyWAP.Models
{
    public class WXInfo
    {
        public string APPID { get; set; }
        public string access_token { get; set; }
        public string expires_in { get; set; }
        public string ticket { get; set; }
        public string errmsg { get; set; }
        public int errcode { get; set; }
        public string noncestr { get; set; }
        public string timestamp { get; set; }
        public string signature { get; set; }
    }
}

Mã JavaScript khởi tạo trên trang web:

var requestStatus = 0;
function shareWX() {
    if (requestStatus != 1) {
        requestStatus = 1;
        var ajaxPara = "url=" + encodeURIComponent(window.location.href.split('#')[0]);
        $.ajax({
            url: '/WXMessage/GetToken',
            dataType: 'json',
            data: ajaxPara,
            success: function (json) {
                if (undefined != json && json !== "") {
                    var jsonObjs = eval(json);
                    wx.config({
                        debug: false,
                        appId: jsonObjs.APPID,
                        timestamp: jsonObjs.timestamp,
                        nonceStr: jsonObjs.noncestr,
                        signature: jsonObjs.signature,
                        jsApiList: [
                            'checkJsApi',
                            'onMenuShareTimeline',
                            'onMenuShareAppMessage',
                            'onMenuShareQQ',
                            'onMenuShareWeibo',
                            'onMenuShareQZone'
                        ]
                    });
                    wx.ready(function () {
                        wx.checkJsApi({
                            jsApiList: [
                                'checkJsApi',
                                'onMenuShareTimeline',
                                'onMenuShareAppMessage',
                                'onMenuShareQQ',
                                'onMenuShareWeibo',
                                'onMenuShareQZone'
                            ],
                            success: function (res) {
                            }
                        });

                        wx.onMenuShareWeibo({
                            title: 'Kiểm tra chia sẻ ManYi',
                            desc: 'Mô tả kiểm tra chia sẻ ManYi',
                            link: 'http://www.manyiaby.com',
                            imgUrl: 'http://www.manyiaby.com/img/logo_2.jpg',
                            success: function () {
                                alert("Chia sẻ thành công");
                            },
                            cancel: function () {
                                alert("Chia sẻ bị hủy");
                            }
                        });
                    });
                    wx.error(function (res) {
                    });
                    requestStatus = 2;
                }
            },
            complete: function () {
                window.setTimeout(function () {
                    requestStatus = 2;
                }, 300);
            }
        });
    }
}

Cuối cùng, đề xuất sử dụng thành phần chia sẻ xã hội Sosh. Giao diện đơn giản giúp website trông tinh tế hơn. Chỉ cần thêm thư viện vào trang là có thể sử dụng.

Thẻ: JavaScript weixin sharing social-media HTML5

Đăng vào ngày 23 tháng 6 lúc 21:20