2016-06-24 12 views
0

7月6日更新:@gettletoのおかげで、私はresponseヘッダーオプションとOPTIONSルートそれは、エラーなしで動作しますが、私は一種の周りに自分の道をハッキングし、APIが脆弱であれば任意の余分ている場合や、率直に言って、不足しているかもしれないもの、responseヘッダがリストされるべきかを理解していません。 「ベストプラクティス」かに私を参照することができ、ガイド誰もがある場合バックボーンアプリ - > PHP/Slim/CorsSlim API:PUTアクセス制御が許可されていません - オリジナルのヘッダーがありません

、それは素晴らしいだろう。私は、初心者のためのガイドを見つけることを試みるのに数時間を費やしましたが、愛はありません。

更新6月27日:私は、バックボーンがthis SO answerに私を導いたPOST、前のサーバにプリフライトリクエストを送信することを発見しました。 OPTIONSルートをAPIに追加しました(下記のコードを参照)。コンソールにXMLHttpRequest cannot load http://foxworkx.dev/bookAPI.php/books. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8081' is therefore not allowed access.を取得しましたが、APIはPOSTが動作することを許可しました!

OPTIONSとPOSTリクエストの両方がステータスを取得している:200 OKを。

だから、私がCorsOptionsを設定し、$アプリに追加しますが、定義されたレスポンスヘッダを持つOPTIONSルートが必要であることを奇妙に思えます。

助けてください。 /アップデート27 June

私はBackboneチュートリアルを通して働いており、Slim3とCorsSlim3を使って簡単なMySQL/PHP APIを構築しました。 GETはエラーなしで動作しています。変わった部分はPOSTがMySQLに挿入されているので、私はそれがコールバックの問題だと思っていますが、私はそれをどのように修正するか考えていません。

大変助かりました。

私のPHPのAPIコード

use \Psr\Http\Message\ServerRequestInterface as Request; 
use \Psr\Http\Message\ResponseInterface as Response; 

require 'vendor/autoload.php'; 

$app = new \Slim\App; 

// CORS 
$corsOptions = array(
    "origin" => array("http://127.0.0.1:8081"), 

    "allowMethods" => array('GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'), 
    "exposeHeaders" => array("X-Requested-With", "Content-Type", "Accept", "Origin", "Authorization"), 
    "allowHeaders" => array("X-Requested-With", "Content-Type", "Accept", "Origin", "Authorization") 
); 
$cors = new \CorsSlim\CorsSlim($corsOptions); 
$app->add($cors); 
// END CORS 

/* 
ROUTES 
*/ 
// GET all 
$app->get('/books', function (Request $request, Response $response) { 
    $sql = "select * FROM bookDB ORDER BY title"; 
    try { 
     $db = getConnection(); 
     $stmt = $db->query($sql); 
     $books = $stmt->fetchAll(PDO::FETCH_OBJ); 
     $db = null; 
     echo json_encode($books); 
    } catch(PDOException $e) { 
     echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    } 
}); 
// OPTIONS (preflighted requests)------NEW 
$app->options('/books', 
    function(Request $request, Response $response, $args) { 
     return $response 
      ->withHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:8081') 
      ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization') 
      ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); 
    } 
); 
// ADD one 
$app->post('/books', function (Request $request, Response $response) { 
    $data = $request->getParsedBody(); 
    $book = []; 
    $book[ 'title' ] = filter_var($data[ 'title' ] , FILTER_SANITIZE_STRING); 
    $book[ 'author' ] = filter_var($data[ 'author' ] , FILTER_SANITIZE_STRING); 
    $book[ 'releaseDate' ] = filter_var($data[ 'releaseDate' ] , FILTER_SANITIZE_STRING); 
    $book[ 'keywords' ] = filter_var($data[ 'keywords' ] , FILTER_SANITIZE_STRING); 

    $sql = "INSERT INTO bookDB (title,author,releaseDate,keywords) VALUES ('" . $book[ 'title' ] . "', '" . $book[ 'author' ] . "', '" . $book[ 'releaseDate' ] . "', '" . $book[ 'keywords' ] . "')"; 
    try { 
     $db = getConnection(); 
     $stmt = $db->prepare($sql); 
     $stmt->execute(); 
    // $book[ 'id' ] = $db->lastInsertId(); 
    // error_log("book id:", $book[ 'id' ]); 
     $db = null; 
    // echo json_encode($book); 



    } catch(PDOException $e) { 
     error_log($e->getMessage()); 
     echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    } 

    // return $response 
    // ->withJson($book) 
    // ->withJson(array(error => array("text" => $e->getMessage()))); 



}); 

そして、私のBackbone.view

 var app = app || {}; 

app.LibraryView = Backbone.View.extend({ 

    events: { 
     'click #add' : 'addBook' 
    }, 

    el: '#books', 

    initialize: function() { 

     this.collection = new app.Library(); 
     this.collection.fetch({ reset:true }); 
     this.render(); 

     this.listenTo(this.collection, 'add', this.renderBook); 
     this.listenTo(this.collection, 'reset', this.render); 
    }, 

    // render library by rendering each book in its collection 
    render: function() { 
     this.collection.each(function(item) { 
      this.renderBook(item); 
     }, 
     this); 
    }, 

    // render a book by creating a BookView and appending the 
    // element it renders to the library's element 
    renderBook: function(item) { 
     var bookView = new app.BookView({ 
      model: item 
     }); 
     this.$el.append(bookView.render().el); 
    }, 

    addBook: function(e) { 

     e.preventDefault(); 

     var formData = {}; 

     $('#addBook div').children('input').each(function(i, el) { 
      if($(el).val() != '') { 
       formData[ el.id ] = $(el).val(); 
      } 
      // Clear input field value 
       $(el).val(''); 
     }); 
     // add to this.collection AND POST the data 
     this.collection.create(formData); 

    } 

}); 

そして、私のPHPのerror_logには:

[24-Jun-2016 09:59:15 America/Los_Angeles] PHP Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0 
[24-Jun-2016 09:59:15 America/Los_Angeles] PHP Warning: Cannot modify header information - headers already sent in Unknown on line 0 

答えて

0

は、あなたからのレスポンスオブジェクトを返すと、これを再試行することができます経路の操作...

return $response->withJson($book); 
return $response->withJson(array(error => array("text" => $e->getMessage()))); 

あなたはサーバー側で、あなたのブートストラップコードの多くを追加した場合はそれが役立つだろう...

編集 あなたは、[オプションと実際のリソース]

+0

両方の要求にヘッダを必要とする@gettleto :私はこのコードを使って何も戻っていません。 – royhink

+0

ああ申し訳ありません。 OPTIONSリクエストと実際のリソースの両方にOPTIONSヘッダーを添付する必要があります。 – geggleto

+0

はい、私は '$ cors = new \ CorsSlim \ CorsSlim($ corsOptions);と考えました。 $ app-> add($ cors); 'を$ appインスタンスにアタッチしていました。いいえ? – royhink

関連する問題