2016-08-13 208 views
0

我正在構建我的第一個Firefox Web擴展,並且正在使用OAuth與API進行集成。在WebExtension中運行多個腳本background.js

當用戶單擊工具欄中的圖標時,會發生什麼情況?它會爲用戶提供一個身份驗證號碼,以便進入網頁。然後他們這樣做,授權我的應用程序並存儲訪問令牌。

我被卡住的地方目前我的代碼依靠彈出窗口保持打開狀態來輪詢來自響應API的響應。我假設我需要在後臺文件中運行民意調查,但我不知道我會如何做到這一點。

我popup.js

// Set Vars 
var successComp = 0; 
// Poll to check for authentication 
function pollAccessToken(device_code, interval) { 
    var request = new XMLHttpRequest(); 
    request.open('POST', 'https://private-anon-535ecb43fa-trakt.apiary-mock.com/oauth/device/token'); 
    request.setRequestHeader('Content-Type', 'application/json'); 
    request.onreadystatechange = function() { 
     if (this.readyState === 4) { 
      switch (this.status) { 
       case 200: 
        // Get Response and put in array 
        var response = JSON.parse(this.responseText); 
        // Save Access Token and Refresh Token to storage 
        chrome.storage.local.set({"access_token": response.access_token, "refresh_token": response.refresh_token}); 
        // Set success notification 
        chrome.runtime.sendMessage({"title": "Trakt for IMDb Authentication Success", "content": "Awesome, you've authenticated your Trakt account! Enjoy using Trakt for IMDb."}); 
        // Set successComp to 1 so clearTimeout doesn't trigger 
        successComp = 1; 
        break; 
       case 400: 
        // Request still pending 
        setTimeout(pollAccessToken.bind(null, device_code).bind(null, interval), interval * 1000); 
        break; 
       case 404: 
        // Display Request not found/invalid error 
        chrome.runtime.sendMessage({"title": "Trakt for IMDb Authentication Error", "content": "Whoops, looks like there was an error authenticating your Trakt account. Please try again."}); 
        break; 
       case 409: 
        // Code already used 
        chrome.runtime.sendMessage({"title": "Trakt for IMDb already approved", "content": "Whoops, looks like you've already approved this code. If you continue to have issues, please try again."}); 
        break; 
       case 410: 
        // Code Expired 
        chrome.runtime.sendMessage({"title": "Trakt for IMDb Authentication Token Error", "content": "Whoops, looks like your token expired and there was an error authenticating your Trakt account. Please try again"}); 
        break; 
       case 418: 
        // Code Denied 
        chrome.runtime.sendMessage({"title": "Trakt for IMDb Authentication Denied", "content": "Oh no, it looks like you denied us access to your account! If you didn't mean to do this, please try again."}); 
        break; 
       case 429: 
        // Slow down polling 
        setTimeout(pollAccessToken.bind(null, device_code).bind(null, interval), interval * 1100); 
        break; 
       default: 
        // Request still pending 
        setTimeout(pollAccessToken.bind(null, device_code).bind(null, interval), interval * 1000); 
        break; 
      } 
     } 
    }; 
    var body = { 
     'code': device_code, 
     'client_id': APP_KEY, 
     'client_secret': APP_SEC 
    }; 
    request.send(JSON.stringify(body)); 
} 
// Get and display authentication 
function outputAuth() { 
    var request = new XMLHttpRequest(); 
    request.open('POST', 'https://private-anon-535ecb43fa-trakt.apiary-mock.com/oauth/device/code'); 
    request.setRequestHeader('Content-Type', 'application/json'); 
    request.onreadystatechange = function() { 
     if (this.readyState === 4) { 
      // Get Response and put in array 
      var response = JSON.parse(this.responseText); 
      // Output authentication data 
      document.body.innerHTML = '<section id="traktLogo"><img src="../icons/trakt-logo.png" width="100px" height="100px" alt="Trakt" /></section><h1>Trakt Authentication</h1><h2>Enter the following code into the activation page.</h2><code>' + response.user_code + '</code><a href="' + response.verification_url + '" id="activation" target="_newtab">Activation Page</a>'; 
      var pollAccess = pollAccessToken(response.device_code, response.interval); 
      setTimeout(stopPolling, response.expires_in * 1000); 
     } 
    }; 
    var body = { 
     'client_id': APP_KEY 
    }; 
    request.send(JSON.stringify(body)); 
} 
// Stop Polling Function 
function stopPolling() { 
    if (successComp === 0) { 
     // Response polling expired 
     clearTimeout(pollAccess); 
     chrome.runtime.sendMessage({"title": "Trakt for IMDb Authentication Timed Out", "content": "Whoops, looks like you took too long in authenticating your Trakt account. Please try again."}); 
    } 
} 
// Check if Access Token Exists 
chrome.storage.local.get("access_token", function (result) { 
    if (result.access_token && typeof result.access_token !== undefined) { 
     // Output Profile Page 
     document.body.innerHTML = '<p>Profile Page</p>'; 
    } else { 
     // Output Authenctication Page 
     outputAuth(); 
    } 
}); 

我background.js

// Display a Notification 
function notify(message) { 
    chrome.notifications.create({ 
     "type": "basic", 
     "title": message.title, 
     "message": message.content, 
     "iconUrl": chrome.extension.getURL("icons/icon-256.png") 
    }); 
} 
/* 
Assign `notify()` as a listener to messages from the content script. 
*/ 
chrome.runtime.onMessage.addListener(notify); 

我很願意投票代碼發送到background.js文件,我只是不太確定我將如何觸發它。同樣非常重要的一點是,我有一些代碼可以阻止pollAccessToken函數在API文檔指定的x分鐘後運行。

完整的源代碼可以在Trakt for IMDb on Github

查詢API文檔預覽可以在Trakt.tv API on Apiary

回答

0

找到我想我已經得到了它與下面的腳本工作。如果有人能告訴我爲什麼,下面這些工作,我怎麼想它會非常讚賞:)

popup.js

// Get and display authentication 
function outputAuth() { 
    var request = new XMLHttpRequest(); 
    request.open('POST', 'https://private-anon-535ecb43fa-trakt.apiary-mock.com/oauth/device/code'); 
    request.setRequestHeader('Content-Type', 'application/json'); 
    request.onreadystatechange = function() { 
     if (this.readyState === 4) { 
      // Get Response and put in array 
      var response = JSON.parse(this.responseText); 
      // Output authentication data 
      document.body.innerHTML = '<section id="traktLogo"><img src="../icons/trakt-logo.png" width="100px" height="100px" alt="Trakt" /></section><h1>Trakt Authentication</h1><h2>Enter the following code into the activation page.</h2><code>' + response.user_code + '</code><a href="' + response.verification_url + '" id="activation" target="_newtab">Activation Page</a>'; 
      chrome.runtime.sendMessage({"type": "pollRequest", "device_code": response.device_code, "interval": response.interval, "expires_in": response.expires_in}); 
     } 
    }; 
    var body = { 
     'client_id': APP_KEY 
    }; 
    request.send(JSON.stringify(body)); 
} 
// Check if Access Token Exists 
chrome.storage.local.get("access_token", function (result) { 
    if (result.access_token && typeof result.access_token !== undefined) { 
     // Output Profile Page 
     document.body.innerHTML = '<p>Profile Page</p>'; 
    } else { 
     // Output Authenctication Page 
     outputAuth(); 
    } 
}); 

background.js

// key.js - Trakt for IMDb by dpDesignz 
var APP_KEY = ''; 
var APP_SEC = ''; 
// Display a Notification 
function notify(message) { 
    chrome.notifications.create({ 
     "type": "basic", 
     "title": message.title, 
     "message": message.content, 
     "iconUrl": chrome.extension.getURL("icons/icon-256.png") 
    }); 
} 
// Set Vars 
var successComp = 0; 
// Poll to check for authentication 
function pollAccessToken(device_code, interval) { 
    var request = new XMLHttpRequest(); 
    request.open('POST', 'https://private-anon-535ecb43fa-trakt.apiary-mock.com/oauth/device/token'); 
    request.setRequestHeader('Content-Type', 'application/json'); 
    request.onreadystatechange = function() { 
     if (this.readyState === 4) { 
      switch (this.status) { 
       case 200: 
        // Get Response and put in array 
        var response = JSON.parse(this.responseText); 
        // Save Access Token and Refresh Token to storage 
        chrome.storage.local.set({"access_token": response.access_token, "refresh_token": response.refresh_token}); 
        // Set success notification 
        notify({"title": "Trakt for IMDb Authentication Success", "content": "Awesome, you've authenticated your Trakt account! Enjoy using Trakt for IMDb."}); 
        // Set successComp to 1 so clearTimeout doesn't trigger 
        successComp = 1; 
        break; 
       case 400: 
        // Request still pending 
        setTimeout(pollAccessToken.bind(null, device_code).bind(null, interval), interval * 1000); 
        break; 
       case 404: 
        // Display Request not found/invalid error 
        notify({"title": "Trakt for IMDb Authentication Error", "content": "Whoops, looks like there was an error authenticating your Trakt account. Please try again."}); 
        break; 
       case 409: 
        // Code already used 
        notify({"title": "Trakt for IMDb already approved", "content": "Whoops, looks like you've already approved this code. If you continue to have issues, please try again."}); 
        break; 
       case 410: 
        // Code Expired 
        notify({"title": "Trakt for IMDb Authentication Token Error", "content": "Whoops, looks like your token expired and there was an error authenticating your Trakt account. Please try again"}); 
        break; 
       case 418: 
        // Code Denied 
        notify({"title": "Trakt for IMDb Authentication Denied", "content": "Oh no, it looks like you denied us access to your account! If you didn't mean to do this, please try again."}); 
        break; 
       case 429: 
        // Slow down polling 
        setTimeout(pollAccessToken.bind(null, device_code).bind(null, interval), interval * 1100); 
        break; 
       default: 
        // Request still pending 
        setTimeout(pollAccessToken.bind(null, device_code).bind(null, interval), interval * 1000); 
        break; 
      } 
     } 
    }; 
    var body = { 
     'code': device_code, 
     'client_id': APP_KEY, 
     'client_secret': APP_SEC 
    }; 
    request.send(JSON.stringify(body)); 
} 
// Stop Polling Function 
function stopPolling() { 
    if (successComp === 0) { 
     // Response polling expired 
     clearTimeout(pollAccess); 
     notify({"title": "Trakt for IMDb Authentication Timed Out", "content": "Whoops, looks like you took too long in authenticating your Trakt account. Please try again."}); 
    } 
} 
// Assign functions based on type 
chrome.runtime.onMessage.addListener(function(data) { 
    switch (data.type) { 
     case "notification": 
      notify(data); 
      break; 
     case "pollRequest": 
      var pollAccess = pollAccessToken(data.device_code, data.interval); 
      setTimeout(stopPolling, data.expires_in * 1000); 
      break; 
    } 
}); 
+0

'如果任何人都可以告訴我爲什麼下面的工作不能如何工作,我想如何 - 「它的工作方式如何?如果是這樣,我不明白爲什麼它不會,如果它不,那麼你需要改變代碼,以便它做到 –

+0

到目前爲止我所能告訴它的確如此。但我不確定我是否以最好的方式做到這一點:) – dpDesignz