2016-06-15 68 views
0

我看到這個問題與另一個問題(webView:didFailLoadWithError -1004: Could not connect to the server while connecting google plus in Phonegap ios)類似,但有點不同,因爲我已經逐行檢查了代碼並且它正在做同樣的事情,但它仍然不適合我。也許也因爲我在不同的版本:iPhone 5S上的iOS 9.3.2),Cordova 6.1.1和cordova-plugin-inappbrowser 1.3.0。InAppBrowser OAUTH didFailLoadWithError 1004「無法連接到服務器。」 「<allow-navigation> not set for url」

我的代碼適用於我的Android,但不適用於iPhone。代碼如下:

var googleapi = { 
    authorize: function(options) { 
     var deferred = $.Deferred(); 
     var authUrl = GOOGLE_CLIENT_API_URL + $.param({ 
      client_id: options.client_id, 
      redirect_uri: options.redirect_uri, 
      response_type: 'code', 
      scope: options.scope 
     }); 
     console.log("authUrl: " + authUrl); 
     var authWindow = window.open(authUrl, "_blank", "location=no,toolbar=no"); // for iOS add 'toolbar=no' 

     //The recommendation is to use the redirect_uri "urn:ietf:wg:oauth:2.0:oob" 
     //which sets the authorization code in the browser's title. However, we can't 
     //access the title of the InAppBrowser. 
     // 
     //Instead, we pass a bogus redirect_uri of "http://localhost", which means the 
     //authorization code will get set in the url. We can access the url in the 
     //loadstart and loadstop events. So if we bind the loadstart event, we can 
     //find the authorization code and close the InAppBrowser after the user 
     //has granted us access to their data. 
     // 
     // To clear the authorization, go to https://accounts.google.com/IssuedAuthSubTokens. 
     $(authWindow).on('loadstart', function(e) { 
      var url = e.originalEvent.url; 
      var code = /\?code=(.+)$/.exec(url); 
      var error = /\?error=(.+)$/.exec(url); 

      if(code || error) { 
       authWindow.close(); 
      } 
      if (code) { 
       //Exchange the authorization code for an access token 
       $.post('https://accounts.google.com/o/oauth2/token', { 
        code: code[1], 
        client_id: options.client_id, 
        client_secret: options.client_secret, 
        redirect_uri: options.redirect_uri, 
        grant_type: 'authorization_code' 
       }).done(function(data) { 
        // use the token we got back from oauth to setup the api. 
        gapi.auth.setToken(data); 
        // load the drive api. 
        loadDriveApi(); 
        deferred.resolve(data); 
       }).fail(function(response) { 
        console.log("Posting code to Google failed. No OAuth token will be returned."); 
        deferred.reject(response.responseJSON); 
       }); 
      } else if (error) { 
       //The user denied access to the app 
       console.log("Error retrieving code from Google."); 
       deferred.reject({ 
        error: error[1] 
       }); 
      } 
     }); 

     return deferred.promise(); 
    } 
}; 

function checkAuth() { 
    if(device.platform === 'browser') { 
     console.log("calling gapi.auth.authorize()"); 
     gapi.auth.authorize(
     { 
      'client_id' : CLIENT_ID, 
      'scope' : SCOPES.join(' '), 
      'immediate' : true 
     }, handleAuthResult); 
    } else { 
     // because this is called only after deviceready(), InAppBrowser is initialized by now: 
     console.log("using the InAppBrowser plugin to authenticate."); 
     window.open = cordova.InAppBrowser.open; 

     googleapi.authorize(
     { 
      'client_id' : CLIENT_ID, 
      'client_secret' : CLIENT_SECRET, 
      'redirect_uri' : REDIRECT_URI, 
      'scope' : SCOPES.join(' ') 
     }, handleAuthResult); 
    } 
} 

/** 
* Handle response from authorization server. 
* 
* @param {Object} authResult Authorization result. 
*/ 
function handleAuthResult(authResult) { 
    var authMenuItem = document.getElementById("menuitemenablegoogledrivebackup"); 
    if (authResult && !authResult.error) { 
     // If already authorized, change menu option to allow user to deny Authorization 
     authMenuItem.innerHTML = l("Disable Google Drive Backup"); 
     loadDriveApi(); 
    } else { 
     alert("Authorization Error: " + authResult.error); 
     console.log("inside handleAuthResult, authResult.error: " + authResult.error); 

     // Show auth menu item, allowing the user to initiate authorization 
     authMenuItem.innerHTML = l("Enable Google Drive Backup"); 
     // use the InAppBrowser to display the authorization window: 
     // var authWindow = window.open(authUrl, '_blank', 'location=no,toolbar=no'); 
     // or? 
     // gapi.auth.authorize(
     // { 
     //  client_id: CLIENT_ID, 
     //  scope: SCOPES.join(' '), 
     //  immediate: false 
     // }, handleAuthResult) 
    } 
} 

/** 
* Load Drive API client library. 
*/ 
function loadDriveApi() { 
    try { 
    gapi.client.load('drive', 'v2', null).then(function(resp) { 
     console.log("Google Drive API v2 loaded successfully."); 
    }, function(reason) { 
     alert('Google Drive API v2 FAILED to load: ' + reason.result.error.message); 
     console.log('Google Drive aPI v2 FAILED to load: ' + reason.result.error.message); 
    }); 
    } catch(err) { 
     alert(err.message); 
     console.log("Google Drive API v2 FAILED to load. Exception: " + err.message); 
    } 
} 

從調試,我看到Android版本調用window.open()調用,它通過loadstart處理先走一次,與原來的URL,但它不包含任何代碼,並沒有錯誤,所以它只是通過。然後redirect_url出現,第二次調用loadstart處理程序(這是由InAppBrowser?),但是這次它有更短的redirect_url並添加了代碼,因此代碼成功用於獲取「$ .post「呼叫。但是,在iOS上,沒有第二次調用loadstart處理程序。

當我在Chrome調試器中運行它時,我沒有遇到任何錯誤,只是無聲的失敗。在Xcode調試器,我得到的錯誤如下:

2016年6月9日20:47:27.014 APass2 [675:398271] web視圖的幀 設置爲{{0,0},{320,524 }} 2016-06-09 20:47:27.015 APass2 [675:398271] 設置WebView的幀爲{{0,0},{320,568}} 2016-06-09 20:47:27.026 APass2 [ 675:398271]螺紋警告:['InAppBrowser']花了 '39 .259033'ms。插件應該使用後臺線程。 2016-06-09 20:47:27.749 APass2 [675:398271] webView:didFailLoadWithError - -1004: 無法連接到服務器。 2016年6月9日20:47:28.955 APass2 [675:398271] ERROR內部導航拒絕 - 爲 URL設置= 'https://content.googleapis.com/static/proxy.html?jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.en.joG9nQvYxYQ.O%2Fm%3D__features__%2Fam%3DAQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCPyXDgCg_S7GlvvvMpztuAZ6V0pEA#parent=file%3A%2F%2F&rpctoken=1268129019' 我的成功

無或失敗的回調被調用。

請幫忙!!!我現在完全處於虧損狀態。

感謝, 愛德華所有的

回答

1

首先,通過查看InAppBrowser文檔,我才知道還有一個「loaderror」事件。只有在iOS上,調用inAppBrowser.open()纔會導致調用「loaderror」處理程序。在「loaderror」處理程序內部,我也能夠獲取url,就像原始代碼在「loadstart」上做的一樣。在Chrome和Safari中同時進行調試我能夠看到url在「loaderror」中與在「loadstart」處理程序中完全相同,並且解析代碼和錯誤的方式完全相同。所以,在第一次剪輯中,我就這樣入侵了,並進入了下一個階段(成功 - 有點)。然後我碰到另一個與<access-navigation>有關的錯誤。搜索了更多,我發現在你的項目的根目錄下的config.xml中有一個可用的配置設置。

地段更多的谷歌搜索指着我的人誰據說用<allow-navigation href="*" />

很顯然,我是不滿意的是廣泛的一個安全漏洞。

所以,最重要的是我需要添加Google API需要訪問配置的網址。xml文件如下:

<allow-navigation href="https://accounts.google.com/*" /> 
<allow-navigation href="https://content.googleapis.com/*" /> 

我仍然需要清理的代碼,並可能簡化了錯誤的「loaderror」處理程序處理,但我有現在的工作!

最令人沮喪的是,這個設置在Android上完全沒有必要,所以我沒有理由懷疑這是問題所在。

謝謝那些花時間看這個的人!

Edward