2016-02-27 15 views
9

Tôi đang xây dựng một Ứng dụng Cordova với các cuộc gọi REST đơn giản.Sự cho phép của Cordova AJAX POST

Vấn đề là khi tôi thực hiện một AJAX với POST, Chrome gửi cho tôi: "XMLHttpRequest không thể tải http://192.168.1.111/project/app đáp ứng cho preflight có hợp lệ mã trạng thái HTTP 405". trên console.

Nhưng, nếu tôi thực hiện cuộc gọi AJAX với GET (về cơ bản trả lại giá trị từ cơ sở dữ liệu), mọi thứ hoạt động như một nét duyên dáng.

gọi AJAX của tôi là:

$.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 handler trong 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; 
} 

gì tôi đã cố gắng:

1 #: Truy cập nguồn gốc trong cấu hình .xml

<access origin="*" /> 

2 #: Thêm connect-src IP MY vào thẻ 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 #: Thêm Access-Control-Allow-Origin trong ứng dụng REST của tôi .htaccess

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

4 #: Thêm mã hỗ trợ trong JavaScript

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

5 #: Để kiểm tra nếu không muốn nói là lỗi trong Server POST, tôi đã sử dụng CURL và làm việc bình thường (thành công)

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

OBS: Tôi đang sử dụng Slim khuôn khổ để REST (http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/)

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

Update # 1:

Tôi đã tải lên cơ sở dữ liệu và ứng dụng của mình lên máy chủ lưu trữ trực tuyến và kết quả vẫn như cũ.

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

Cập nhật # 2:

Làm các xét nghiệm khác, tôi nhận thấy rằng loại bỏ các contentType: "application/json " trình gỡ lỗi hiển thị lỗi khác.

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

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

Đã hai ngày mà tôi đang cố gắng để giải quyết này và không có gì xuất hiện như một giải pháp.Tôi thực sự buồn.

+0

Máy chủ của bạn không hỗ trợ bài đăng, bạn có thể hiển thị cho bạn mã hành động? – Naumov

+0

@Naumov Xin lỗi, tôi đã quên điểm đó, tôi đã cập nhật câu hỏi của mình. POST máy chủ đang hoạt động, tôi đã sử dụng CURL để kiểm tra nó. – reidark

+0

Tôi nghĩ rằng điều này có thể giúp bạn http://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript và 'url:" http: //192.168 .1.111/project/app "' thử url với out shema 'http: //' – Naumov

Trả lời

-1

Sau khi đọc khoảng 60 câu hỏi trong StackOverflow và những điều về CORS, PHP và Kiểm soát truy cập tôi đạt đến "giải pháp đơn giản".

Nhưng, trước khi tôi đăng giải pháp, tôi muốn nói rằng loại sự cố quá nhiều "chung" và lỗi có thể ở bất kỳ đâu.

Ok, trước tiên, giải pháp không hoạt động trên Chrome. Chrome sẽ luôn trả về mã trạng thái 405, nhưng, chạy ứng dụng cordova trong các thiết bị thực (hoặc mô phỏng) giải pháp hoạt động như một sự quyến rũ. Có, đây là về việc Chrome chặn các yêu cầu miền chéo.

Bước đầu tiên:

Dữ liệu trong AJAX phải được đặt với '{}'. Vâng, tôi không biết về điều đó. Nếu bạn cần, hãy chơi xung quanh JSON.stringify để dễ dàng hơn nhiều.

$.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); 
    } 
}); 

bước thứ hai:

Trong REST API bạn cần kích hoạt Access-Control-Allow-Headers cho những thứ làm việc.

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

Hiện tại, APP của tôi hoạt động bình thường với các giải pháp này. Tôi rất vui khi biết về các giải pháp khác (đối với công việc trong Chrome).

Cảm ơn các bạn!

1

Tôi nghĩ rằng vấn đề có thể là thế này:

lỗi preflight là do thực tế mà khách hàng đang thực hiện một yêu cầu OPTIONS (trước bưu điện); yêu cầu này không được máy chủ xử lý chính xác. Vì yêu cầu OPTIONS không được xử lý bởi máy chủ nên POST tiếp theo không được xử lý. Vì vậy, trước hết hãy kiểm tra với trình gỡ rối (hoặc đánh hơi trên máy chủ), đó là yêu cầu gây ra lỗi mà bạn đề cập đến. Nếu đoán của tôi là phải xử lý nó và bạn sẽ thấy rằng POST tiếp theo sẽ được excuted một cách chính xác bởi khách hàng.

+1

Có, trong trình gỡ lỗi OPTIONS xuất hiện trước lỗi chính. Nhưng, tôi không biết chính xác cái này là gì. – reidark

+0

Hoàn hảo! Bạn phải xử lý yêu cầu OPTIONS trên máy chủ. – pinturic

Các vấn đề liên quan