2017-09-04 46 views
2

我努力獲得離子this.http.post工作。捲曲POST作品,但離子這個.http.post不

如果我在終端使用捲曲它的偉大工程:

curl -v -X POST \ 
    https://myuser-name:[email protected]:5984/_session \ 
    -d 'name=app&password=ijF3Ui7VYVbbSejmwsnVVo' 

它給了我下面的輸出:

Note: Unnecessary use of -X or --request, POST is already inferred. 
* Trying 37.1.96.50... 
* TCP_NODELAY set 
* Connected to app.mysite.com (37.1.96.49) port 5984 (#0) 
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 
* Server certificate: app.mysite.com 
* Server certificate: COMODO RSA Domain Validation Secure Server CA 
* Server certificate: COMODO RSA Certification Authority 
* Server auth using Basic with user 'myuser-name' 
> POST /_session HTTP/1.1 
> Host: app.mysite.com:5984 
> Authorization: Basic cDpkTUQySzg0a2lqRjNVaTdWWVZiYlNlam13c25WVm8= 
> User-Agent: curl/7.54.0 
> Accept: */* 
> Content-Length: 52 
> Content-Type: application/x-www-form-urlencoded 
> 
* upload completely sent off: 52 out of 52 bytes 
< HTTP/1.1 200 OK 
< Set-Cookie: AuthSession=ZWhzLWFwcDo1OUFENThGRjruBtcPzHcqc1sC9WXrcWI7R27_Mg; Version=1; Secure; Path=/; HttpOnly 
< Server: CouchDB/1.6.1 (Erlang OTP/18) 
< Date: Mon, 04 Sep 2017 13:45:35 GMT 
< Content-Type: text/plain; charset=utf-8 
< Content-Length: 43 
< Cache-Control: must-revalidate 
< 
{"ok":true,"name":null,"roles":["_admin"]} 
* Connection #0 to host app.mysite.com left intact 

我離子POST代碼如下所示:

login(callerName:string):any 
 
    // Make sure we have a CouchDB session so that PouchDB can access the CouchDB database 
 
    { 
 
    console.log('Authentication: login(): Login function called from ' + callerName); 
 

 
    return new Promise(resolve => { 
 
     let headers = new Headers(); 
 
     headers.append('Content-Type', 'application/json'); 
 

 
     let credentials = { 
 
     name: COUCHDB_USER, 
 
     password: COUCHDB_PASSWORD 
 
     }; 
 

 
     let result = { 
 
     success: false, 
 
     data: [] 
 
     }; 
 

 
     console.log('Authentication: login(): credentials = ' + JSON.stringify(credentials)); 
 

 
     // NOTE: 
 
     // 
 
     // If POST is called with COUCHDB_SERVER with no auth in the url I get the error: Response with status: 401 Unauthorized for URL: https://app.mysite.com:5984/_session" 
 
     //  
 
     // If POST is called with COUCHDB_SERVER WITH auth in url I get the error: Response with status: 0 for URL: null 
 
     // This 'might' mean: 
 
     //  Timeout from server 
 
     //  Request not sent 
 
     //  Requesting an unreachable url 
 
     //  ... 
 
     // This WORKS with curl in terminal 
 
     // 
 
     // With auth in url: https://myuser-name:[email protected]:5984/_session 
 
     // Without auth in url: https://app.mysite.com:5984/_session 
 
     // 
 
     this.http.post(COUCHDB_SERVER + '/_session', JSON.stringify(credentials), {headers: headers}) 
 
     .subscribe(res => { 
 
      var details = res.json(); 
 
      console.log('Authentication: login(): SuperLogin successful login: res = ' + JSON.stringify(details)); 
 

 
      result.success = true; 
 
      result.data = details; 
 
      resolve(result); 
 
      }, 
 
      (err) => { 
 
      console.log('Authentication: login(): Login failed err = ' + err); 
 

 
      let details = err.json(); 
 
      result.success = false; 
 
      result.data = details; 
 
      resolve(result); 
 
      }); 
 
    }); 
 
    }

如果我嘗試POST離子在URL中沒有權威性,我得到一個合理的錯誤消息:

Response with status: 401 Unauthorized for URL: https://app.mysite.com:5984/_session" 

但是,如果我添加權威性的網址,我得到一個錯誤消息並沒有告訴我什麼問題是:

Response with status: 0 for URL: null 

我不能工作爲什麼它與curl工作,但不在離子http.post內。

我有同樣的問題,無論我運行ionic serve還是我在iPhone上運行應用程序。

UPDATE

我已經運行在Chrome離子App和現在有一個更好的錯誤:

error: "unauthorized", reason: "Authentication required." 

所以很顯然我沒有收到POST請求正確的,但不能看爲什麼。

+1

由curl和ionic發送的HTTP請求是不同的。 curl發送的HTTP請求的'Content-Type'是'application/x-www-form-urlencoded',離子發送的是'application/json'。你可以讓他們一致並再試一次嗎? – shaochuancs

+0

@shaochuancs不幸的是我仍然得到同樣的錯誤。我更新了我的問題,以顯示在Chrome上我現在得到了一個明智的錯誤:錯誤:「未經授權」,原因:「需要身份驗證。」所以很明顯,我沒有正確地形成我的POST請求 –

+1

是的...你已經通過'JSON.stringify(憑證)'將它轉換爲字符串。但沒有必要,只需將'credential'作爲this.http.post的第二個參數傳遞就可以了。官方示例請參閱https://angular.io/guide/http。 – shaochuancs

回答

3

由於this.http.post的使用不正確:第二個參數應該是HTTP請求正文對象(JSON,credential對象),而不是字符串,因此身份驗證在離子中失敗。例如,請參閱https://angular.io/guide/http

代碼發送HTTP請求將是:

this.http.post(COUCHDB_SERVER + '/_session', credentials, {headers: headers})... 

它工作在捲曲,但不是在離子 - 那是因爲由捲曲發送的HTTP請求的Content-Typeapplication/x-www-form-urlencoded,和捲曲的語法是正確的。

我應該在URL中添加auth嗎? - 我想這意味着URL中的myuser-name:[email protected]部分。答案是否定:捲曲(在請求中添加Authorization標題),但在瀏覽器中不起作用,請檢查Pass username and password in URL for HTTP Basic Auth瞭解詳情。

更新:似乎在CouchDB中強制執行基本身份驗證。爲了滿足它,可以在HTTP請求中手動添加Authorization標頭:

headers.append('Authorization', 'Basic ' + window.btoa(username + ':' + password)) 
+0

我已經從網址中刪除了身份驗證,我的http.post現在按照您的示例。我現在正在彈出一個「需要身份驗證」模式。 –

+0

我閱讀Pass用戶名的帖子,非常有用,謝謝。它解釋了很多,我應該知道,但沒有。特別是爲什麼捲曲的作品,但郵差沒有。有趣的是,我無法讓郵遞員與我的POST通話一起工作。也許這是連接? –

+0

@BillNoble看起來您的CouchDB中啓用了基本身份驗證。爲了滿足彈出的「需要驗證」模式,您可以手動添加離子代碼中的Authorization標頭。如:'headers.append('授權','基本'+ window.btoa(用戶名+':'+密碼))' – shaochuancs