2016-02-27 146 views
9

我正在用簡單的REST調用構建一個Cordova APP。Cordova AJAX POST權限

的問題是,當我提出用POST一個AJAX,Chrome會將我:「的XMLHttpRequest無法加載http://192.168.1.111/project/app預檢響應具有無效的HTTP狀態代碼405。」在控制檯上。

但是,如果我使用GET進行AJAX調用(基本上從數據庫返回一個值),這些事情就像一個魅力。

我的AJAX調用是:在REST

require 'Slim/Slim.php'; 
$app = new Slim(); 
$app->post('/app', 'addApp'); 
$app->run(); 

function addApp() { 
    error_log('addApp\n', 3, '/var/tmp/php.log'); 
    $request = Slim::getInstance()->request(); 
    $callback = json_decode($request->getBody()); 
    $sql = "INSERT INTO app (name) VALUES (:name)"; 
    try { 
     $db = getConnection(); 
     $stmt = $db->prepare($sql); 
     $stmt->bindParam("name", $callback->name); 
     $stmt->execute(); 
     $callback->id = $db->lastInsertId(); 
     $db = null; 
     echo json_encode($callback); 
    } catch(PDOException $e) { 
     error_log($e->getMessage(), 3, '/var/tmp/php.log'); 
     echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    } 
} 

function getConnection() { 
    $dbhost="localhost"; 
    $dbuser="myuser"; 
    $dbpass="mypass"; 
    $dbname="mydb"; 
    $dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass); 
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    return $dbh; 
} 

$.ajax({ 
    url: "http://192.168.1.111/project/app", 
    type: "POST", 
    dataType: "json", 
    contentType: 'application/json', 
    data: { 
    "name": "Cordova" 
    }, 
    success: function() { 
    navigator.notification.alert("Success!"); 
    }, 
    error: function(jqXHR, textStatus, errorThrown) { 
    console.log(textStatus + jqXHR.responseText); 
    } 
}); 

POST處理程序我已經試過:

1#:訪問起源於配置.xml

<access origin="*" /> 

2#:在連接-SRC我的IP加入meta標籤

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; connect-src 'self' http://192.168.1.111"> 

3#:添加訪問控制允許來源在我的REST的應用程序的.htaccess

Header add Access-Control-Allow-Origin "*" 
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT" 

4#:添加支持CORS在JavaScript

$.support.cors = true; 
$.mobile.allowCrossDomainPages = true; 

5#:要檢查是不是錯誤Server後,我用捲曲和工作正常(成功)

curl -i -X POST -H 'Content-Type: application/json' -d '{"name": "Cordova"}' http://192.168.1.111/project/app 

OBS:我使用超薄框架,REST(http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/

================

更新#1:

我已將我的數據庫和應用程序上傳到在線主機,結果仍然相同。

================

更新#2:

做一套測試中,我注意到,除去的contentType:「應用/ JSON 「調試器顯示另一個錯誤。

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'name' cannot be empty 

================

它已經兩天,我試圖解決這一點,並沒有出現作爲解決方案。我真的很傷心。

+0

你服務器不支持帖子,你可以告訴你動作碼? – Naumov

+0

@Naumov對不起,我忘了那一點,我已經更新了我的問題。服務器POST正在工作,我用CURL來測試它。 – reidark

+0

我想也許這可以幫助你http://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript和'url:「http://192.168 .1.111/project/app「'嘗試帶出shema網址'http://' – Naumov

回答

-1

在閱讀了StackOverflow中的大約60個問題以及關於CORS,PHP和訪問控制的內容之後,我得出了一個「簡單的解決方案」。

但是,在我發佈解決方案之前,我想說的是,這種類型的問題太「普遍」,錯誤可能在任何地方。

好的,首先,該解決方案不適用於Chrome。 Chrome將始終返回405狀態碼,但是,在真實設備(或模擬器)中運行cordova應用程序時,解決方案就像魅力一樣。是的,這是關於Chrome阻止跨域請求的。

第一步:

AJAX中的數據必須放在'{}'中。是的,我不知道這一點。如果您需要,可以使用JSON.stringify來簡化操作。

$.ajax({ 
    url: "http://myonlineurl.com/project/app", 
    type: "POST", 
    dataType: "json", 
    contentType: 'application/json', 
    data: '{ "name": "Cordova", "another_thing" : "thing" }', 
    success: function() { 
     navigator.notification.alert("Success!"); 
    }, 
    error: function(jqXHR, textStatus, errorThrown) { 
     console.log(textStatus + jqXHR.responseText); 
    } 
}); 

第二步:

在REST API,你需要啓用訪問控制允許報頭爲工作的事情。

<?php header('Access-Control-Allow-Headers: X-Requested-With, origin, content-type'); ?> 

目前我的APP在這些解決方案中正常工作。我很高興聽到其他解決方案(用於在Chrome中工作)。

謝謝你們!

1

我想問題可能是這樣的:

預檢錯誤是由於一個事實,即客戶端作出OPTIONS請求(職前);這個請求不能被服務器正確處理。由於OPTIONS請求沒有被服務器處理,所以下一次POST不被處理。因此,首先檢查調試器(或在服務器上嗅探),這是導致您提到的錯誤的請求。如果我的猜測是正確的,那麼你會看到下一次POST會被客戶正確執行。

+1

是的,在調試器中,OPTIONS出現在主錯誤之前。但是,我不知道這究竟是什麼。 – reidark

+0

完美!您必須處理服務器上的OPTIONS請求。 – pinturic