如何使用访问令牌来增加Stack Exchange API的配额

时间:2015-04-20 17:31:55

标签: javascript html access-token rate-limiting stackexchange-api

您好我正在创建一个Web仪表板来获取堆栈流量数据并显示给用户。

这是我的index.html页面:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" type="text/css" href="css/base.css">
    <title>Stack Overflow dashboard</title>
</head>

<body>

    <div id="container">

        <section role="region">
            <header>
                <h1>
                    <img src="images/logo.png" alt=""> dashboard
                </h1>
            </header>
        </section>


        <div id="main">
            <p>
                Activity Dashboard.
                Remaining requests (Standard Rate Limit) <span id="remaining-requests"></span>
            </p>
            <p id="error">

            </p>

            <div>

                <form id="selection-form">
                    <label for="stack-overflow-tag">Tag:</label>
                    <input id="stack-overflow-tag" list="popular-tags">
                    <datalist id="popular-tags">
                        <option value="Java">
                        <option value="JavaScript">
                        <option value="HTML">
                    </datalist>

                    <label for="start-date">Dates</label>
                    <input type="date" id="start-date" value="2014-04-01">
                    <input type="date" id="end-date" value="2014-05-01">

                    <label for="time-period">Period</label>
                    <select id="time-period">
                        <option value="month" selected>Month</option>
                        <option value="all_time">All time</option>
                    </select>

                    <input type="submit" id="check-reports" value="Check">
                </form>
            </div>

            <div id="results">

                <section>
                    <h2>Questions (based on dates above)</h2>
                    <table>
                        <tr>
                            <th>With activity</th>
                            <td id="questions-with-activity"></td>
                        </tr>
                        <tr>
                            <th>Unanswered *</th>
                            <td id="unanswered-questions"></td>
                        </tr>
                        <tr>
                            <th>Results</th>
                            <td id="questions-results"></td>
                        </tr>
                        <tr>
                            <td colspan="2">* = (must have at least one upvoted answer to be considered answered)</td>
                        </tr>
                    </table>
                </section>

                <section>
                    <h2>Top answerers (based on time period above)</h2>
                    <div id="top-answerers"></div>
                </section>

                <section>
                    <h2>Unanswered questions *</h2>
                    <div id="unanswered"></div>
                </section>

                <section>
                    <h2>Frequently asked questions</h2>
                    <div id="faq"></div>
                </section>

                <section>
                    <h2>Related tags</h2>
                    <div id="related-tags"></div>
                </section>

                <section>
                    <h2>Top askers (based on time period above)</h2>
                    <div id="top-askers"></div>
                </section>
            </div>
        </div>


    </div>

    <script type="text/javascript" src="js/base.js"></script>

</body>
</html>

现在这是我的base.js页面,我正在拨打电话:

     "use strict";
        (function() {
    var tag = document.querySelector("#stack-overflow-tag"),
        startDate = document.querySelector("#start-date"),
        endDate = document.querySelector("#end-date"),
        timePeriod = document.querySelector("#time-period"),
        year = new Date().getFullYear(),
        month = new Date().getMonth() + 1,
        daysinMonth = 31,
        questions = {
            //tag : "firefox-os",
            startDate : "2014-05-01",
            endDate : "2014-05-31",
            timePeriod : "month",
            withActivity : {
                total : 0
            },
            unanswered :  {
                total : 0
            },
            topAskers : {
                items  : []
            },
            faq : {
                items  : []
            },
            relatedTags : {
                items  : []
            }
        };

    // Setting up the form
    switch (month){
        case 2:
            daysinMonth = 28;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            daysinMonth = 30;
            break;
        default:
            daysinMonth = 31;
    }

    month = (month < 10)? "0" + month : month;
    startDate.value = year + "-" + month + "-01";
    endDate.value = year + "-" + month + "-" + daysinMonth;

    document.querySelector("#selection-form").onsubmit = function (evt) {
        checkReports();
        evt.preventDefault();
    };


    function addResults (type) {
        var questionsWithActivity = questions.withActivity.total,
            unansweredQuestions = questions.unanswered.total,
            percentageUnanswered = (questionsWithActivity > 0)? parseFloat((unansweredQuestions/questionsWithActivity) * 100).toFixed(2) : "100";
    // Popular tags, for filling the <datalist> element
    if (type === "popularTags") {
        var popularTagsList = document.querySelector("#popular-tags"),
            popularTags = questions.popularTags.items,
            popularTagsResults = "";
        for (var i=0,l=popularTags.length, tag; i<l; i++) {
            tag = popularTags[i];
            popularTagsResults += "<option value=\"" + tag.name + "\">";
        }
        popularTagsList.innerHTML = popularTagsResults;
    }

    // With activity
    if (type === "withActivity") {
        document.querySelector("#questions-with-activity").innerHTML = questionsWithActivity;
    }

    // With activity or unanswered, to compare results
    if (type === "withActivity" || type === "unanswered") {
        document.querySelector("#questions-results").innerHTML = percentageUnanswered + "% unanswered";
    }

    // Unanswered
    if (type === "unanswered") {
        document.querySelector("#unanswered-questions").innerHTML = unansweredQuestions;

        var unanswered = document.querySelector("#unanswered"),
            allUnanswered = questions.unanswered.items;
        if (allUnanswered) {
            var totalUnanswereds = (allUnanswered.length > 10)? 10 : allUnanswered.length,
                unansweredResults = "<ul>";

            for (var j=0,jl=totalUnanswereds, question; j<jl; j++) {
                question = allUnanswered[j];
                unansweredResults += "<li>" +
                                "<a href=\"" + question.link + "\">" +
                                question.title + "</a><br>" +
                                "<small>" + question.tags.toString(", ") + "</small></li>";
            }
            unansweredResults += "</ul>";
            unanswered.innerHTML = unansweredResults;
        }
    }

    // Top answerers
    if (type === "topAnswerers") {
        var topAnswerers = document.querySelector("#top-answerers"),
            allTopAnswerers = questions.topAnswerers.items;
        if (allTopAnswerers) {
            var totalTopAnswerers = (allTopAnswerers.length > 5)? 5 : allTopAnswerers.length,
                topAnswerersResults = "<ul>";

            for (var k=0,kl=totalTopAnswerers, answerer; k<kl; k++) {
                answerer = allTopAnswerers[k];
                topAnswerersResults += "<li>" +
                                    "<a href=\"" + answerer.user.link + "\">" +
                                    "<img src=\"" + answerer.user.profile_image + "\" alt=\"\">" +
                                    answerer.user.display_name + "</a>" + ", Score: " + answerer.score + " (" +
                                    answerer.post_count + " question" + ((answerer.post_count > 1)? "s" : "") + ")</li>";
            }
            topAnswerersResults += "</ul>";
            topAnswerers.innerHTML = topAnswerersResults;
        }
    }

    // Top askers
    if (type === "topAskers") {
        var topAskers = document.querySelector("#top-askers"),
            allTopAskers = questions.topAskers.items;
        if (allTopAskers) {
            var totalTopAskers = (allTopAskers.length > 5)? 5 : allTopAskers.length,
                topAskersResults = "<ul>";

            for (var m=0,ml=totalTopAskers, asker; m<ml; m++) {
                asker = allTopAskers[m];
                topAskersResults += "<li>" +
                                    "<a href=\"" + asker.user.link + "\">" +
                                    "<img src=\"" + asker.user.profile_image + "\" alt=\"\">" +
                                    asker.user.display_name + "</a>" + ", " + asker.post_count + " question" + ((asker.post_count > 1)? "s" : "") + "</li>";
            }
            topAskersResults += "</ul>";
            topAskers.innerHTML = topAskersResults;
        }
    }

    // Frequently asked questions
    if (type === "faq") {
        var faq = document.querySelector("#faq"),
            allFaq = questions.faq.items;
        if (allFaq) {
            var totalFaqs = (allFaq.length > 10)? 10 : allFaq.length,
                faqResults = "<ul>";

            for (var n=0,nl=totalFaqs, faqQuestion; n<nl; n++) {
                faqQuestion = allFaq[n];
                faqResults += "<li>" +
                                "<a href=\"" + faqQuestion.link + "\">" +
                                faqQuestion.title + "</a><br>" +
                                "<small>" + faqQuestion.tags.toString(", ") + "</small></li>";
            }
            faqResults += "</ul>";
            faq.innerHTML = faqResults;
        }
    }

    // Related tags
    if (type === "relatedTags") {
        var relatedTags = document.querySelector("#related-tags"),
            allRelatedTags = questions.relatedTags.items;
        if (allRelatedTags) {
            var totalRelatedTags = (allRelatedTags.length > 10)? 10 : allRelatedTags.length,
                relatedTagsResults = "<ul>";

            for (var o=0,ol=totalRelatedTags, relatedTag; o<ol; o++) {
                relatedTag = allRelatedTags[o];
                relatedTagsResults += "<li>" +
                                "<a href=\"http://stackoverflow.com/questions/tagged/" + relatedTag.name + "\">" +
                                relatedTag.name + "</a></li>";
            }
            relatedTagsResults += "</ul>";
            relatedTags.innerHTML = relatedTagsResults;
        }
    }
}

function showErrors (name, msg) {
    var error = document.querySelector("#error");
    error.innerHTML = name + "<br>" + msg;
}

function getItems(type, url) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            //console.log("Type: " + type);
            //console.log(xhr.response);
            var response = xhr.response,
                quotaRemaining = response.quota_remaining;

            if (response.error_message) {
                showErrors(response.error_name, response.error_message);
            }
            else {
                questions[type] = response;
                addResults(type);
            }

            // Remining requests today from your IP
            if (quotaRemaining) {
                document.querySelector("#remaining-requests").innerHTML = quotaRemaining;
            }
        }
    };

    xhr.open("GET", url, true);
    xhr.responseType = "json";
    xhr.send(null);
}

function getQuestionsWithActivity () {
    // All questions for a certain time period - http://api.stackexchange.com/docs/search
    getItems("withActivity", "http://api.stackexchange.com/2.2/search?fromdate=" + questions.startDate + "&todate=" + questions.    endDate + "&order=desc&sort=activity&tagged=" + questions.tag + "&site=stackoverflow&filter=!9WA((MBIa");
}

function getUnansweredQuestions () {
    // All questions without an answer for a certain time period - http://api.stackexchange.com/docs/unanswered-questions
    // "At this time a question must have at least one upvoted answer to be considered answered"
    getItems("unanswered", "http://api.stackexchange.com/2.2/questions/unanswered?fromdate=" + questions.startDate + "&todate=" + questions.endDate + "&order=desc&sort=activity&tagged=" + questions.tag + "&site=stackoverflow&filter=!9WA((MBIa");
}

function topAnswerers () {
    getItems("topAnswerers", "http://api.stackexchange.com/2.2/tags/" + questions.tag + "/top-answerers/" + questions.timePeriod + "?site=stackoverflow");
}

function topAskers () {
    getItems("topAskers", "http://api.stackexchange.com/2.2/tags/" + questions.tag + "/top-askers/" + questions.timePeriod + "?site=stackoverflow");
}

function faq () {
    getItems("faq", "http://api.stackexchange.com/2.2/tags/" + questions.tag + "/faq?site=stackoverflow");
}

function relatedTags () {
    getItems("relatedTags", "http://api.stackexchange.com/2.2/tags/" + questions.tag + "/related?site=stackoverflow");
}

function checkReports () {
    questions.tag = tag.value;
    questions.startDate = startDate.value;
    questions.endDate = endDate.value;
    questions.timePeriod = timePeriod.value;

    // Get reports
    getQuestionsWithActivity();
    getUnansweredQuestions();
    topAnswerers();
    topAskers();
    faq();
    relatedTags();
}

function getPopularTags () {
    getItems("popularTags", "http://api.stackexchange.com/2.2/tags?pagesize=100&order=desc&sort=popular&site=stackoverflow");
}

// Run automatically at page load to pre-populate the <datalist> element
getPopularTags();
})();

虽然这有效但我有一个问题,我的速率限制为每个IP地址只有300 api请求。我已注册Stack Exchange应用程序,通过access_token合并客户ID /密钥,每天最多可以处理10,000个请求。

我该怎么做: 我查看了这些相关信息: https://api.stackexchange.com/docs/js-lib http://api.stackexchange.com/docs/authentication

这是给出的例子:

$(function(){
      // Initialize library
        SE.init({
            // Parameters obtained by registering an app, these are specific to the SE
            //   documentation site
            clientId: 123,
            key: '8hghjghghQ((',
            // Used for cross domain communication, it will be validated
            channelUrl: 'https://maxpowers.github.io',
            // Called when all initialization is finished
            complete: function(data) {
                $('#login-button')
                    .removeAttr('disabled')
                    .text('Run Example With Version '+data.version);
            }
        });

      // Attach click handler to login button
        $('#login-button').click(function() {

            // Make the authentication call, note that being in an onclick handler
            //   is important; most browsers will hide windows opened without a
            //   'click blessing'
            SE.authenticate({
                success: function(data) {
                    alert(
                        'User Authorized with account id = ' +
                        data.networkUsers[0].account_id + ', got access token = ' +
                        data.accessToken
                    );
                },
                error: function(data) {
                    alert('An error occurred:\n' + data.errorName + '\n' + data.errorMessage);
                },
                networkUsers: true
            });
        });
    });

我想对这些数据进行硬编码,我不希望用户进行身份验证。如何使用访问令牌来实现此功能?

任何帮助都会很棒!

好的所以我回去了这个

我正在做的是将其添加到base.js:

 '$(function(){
        var scriptLoc = 'https://api.stackexchange.com/js/2.0/all.js';



if (window.location.protocol == "https:" ) {
                var script = document.createElement('script');
                script.type = 'text/javascript';
                script.src = scriptLoc;

                document.getElementsByTagName('head')[0].appendChild(script)
            }else{
                window.SE = { init: function(){}, authenticate: function(){} };
            }
        });


        $(function(){
    // Initialize library
            SE.init({
                // Parameters obtained by registering an app, these are specific to the SE
                //   documentation site
                clientId: 1111,
                key: '1111',
                // Used for cross domain communication, it will be validated
                channelUrl: 'https://api.stackexchange.com/docs/proxy',
                // Called when all initialization is finished
                complete: function(data) {
                    $('#login-button')
                        .removeAttr('disabled')
                        .text('Run Example With Version '+data.version);
                }
            });

    // Attach click handler to login button
            $('#login-button').click(function() {

                // Make the authentication call, note that being in an onclick handler
                //   is important; most browsers will hide windows opened without a
                //   'click blessing'
                SE.authenticate({
                    success: function(data) {
                        alert(
                            'User Authorized with account id = ' +
                            data.networkUsers[0].account_id + ', got access token = ' +
                            data.accessToken
                        );
                    },
                    error: function(data) {
                        alert('An error occurred:\n' + data.errorName + '\n' + data.errorMessage);
                    },
                    networkUsers: true
                });
            });
        });'

现在我将其添加到index.html:

   '<input type="submit" id="check-reports" value="Check">
            <div class="https-only">
                <button id="login-button">authbutton</button>
            </div>'

当我得到它时,我应该能够以开发者身份登录,然后能够获得10,000个请求,但我得到的是 我得到的错误是找不到引用此函数的$。

$(function(){
    var scriptLoc = 'https://api.stackexchange.com/js/2.0/all.js';

    if (window.location.protocol == "https:" ) {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = scriptLoc;

        document.getElementsByTagName('head')[0].appendChild(script)
    }else{
        window.SE = { init: function(){}, authenticate: function(){} };
    }
});

我删除了该功能,我得到的下一个错误是找不到引用此内容的$:

$(function(){
// Initialize library
        SE.init({
            // Parameters obtained by registering an app, these are specific to the SE
            //   documentation site
            clientId: 111,
            key: '1111',
            // Used for cross domain communication, it will be validated
            channelUrl: 'https://api.stackexchange.com/docs/proxy',
            // Called when all initialization is finished
            complete: function(data) {
                $('#login-button')
                    .removeAttr('disabled')
                    .text('Run Example With Version '+data.version);
            }
        });

我可能做错了什么?

0 个答案:

没有答案