2014-09-08 3 views
3

레일 API를 사용하고 각도를 사용하여 프론트 엔드에 전원을 공급하기 위해 rails-api 보석을 사용하고 있습니다. $ http를 사용할 때마다 data 대신 params을 전달하면 작동합니다. 다음은 사용자가 로그인하고 새 세션을 만들려고과 예입니다 :

'use strict'; 

app.controller('LoginCtrl', function($scope, $location, $http, tokenHandler) { 
    $scope.login = function() { 
    $http({ 
     url: 'http://localhost:3000/api/admins/sign_in', 
     method: 'POST', 
     params: $scope.admin 
    }).success(function(data) { 
     if (data.success) { 
     $scope.ngModel = data.data.data; 
     tokenHandler.set(data.data.auth_token); 
     $location.path('/admin/blog'); 
     } else { 
     $scope.ngModel = data; 
     $scope.user.errors = data.info; 
     } 
    }).error(function(msg) { 
     $scope.admin.errors = 'Something is wrong. Please try again.'; 
    }); 
    }; 
}); 

을하는 경우 대신 PARAMS의 내가 data: { admin: $scope.admin }을 사용, 레일은 params[:admin]이 전무는 것을 나에게 불평. 전혀 오지 않는 것 같습니다.

Started POST "/api/admins/[email protected]&password=[FILTERED]" for 127.0.0.1 at 2014-09-07 20:08:04 -0400 
Processing by Admin::SessionsController#create as HTML 
    Parameters: {"email"=>"[email protected]", "password"=>"[FILTERED]"} 

어떤 내가 작업 할 수 있습니다 : 나는 PARAMS를 사용하는 경우

그러나,이 얻을. 요청이 HTML로 처리 될 때에 만 작동하는 것처럼 보이는 것은 이상한 일입니다. 내가 data를 사용하는 경우,이 얻을 :
Started OPTIONS "/api/admins/sign_in" for 127.0.0.1 at 2014-09-07 20:36:24 -0400 
Processing by Admin::SessionsController#create as */* 

그것은 */*에 의해 처리를 말할 생각인가? 나는 그것이 구체적으로 json에 의해 처리되기로되어 있다는 것을 이해해야한다고 생각한다.

내 세션 컨트롤러는 다음과 같습니다

class Admin::SessionsController < Devise::SessionsController 
    skip_before_filter :verify_authenticity_token 

    before_filter :authenticate_user!, except: [:create] 
    respond_to :json 

    # ... 
end 

이상한 것은 내가 확실히 단지 data: { admin: $scope.admin }를 사용하여 첫 번째 작업 시간을 가지고,하지만 그 이후의 PARAMS 내가 params: $scope.admin를 사용하지 않으면 나오지 않을 것 같다. ALSO

:

I 인증을 위해 고안를 사용하고, 나는 내와 ApplicationController이를 추가했다 : 지금이 전에 처리

class ApplicationController < ActionController::API 
    include ActionController::MimeResponds 

    before_filter :set_cors_headers 
    before_filter :cors_preflight 

    private 

    def set_cors_headers 
     headers['Access-Control-Allow-Origin'] = AppConfig.client['origin'] 
     headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS' 
     headers['Access-Control-Allow-Headers'] = '*' 
     headers['Access-Control-Max-Age'] = "3628800" 
    end 

    def cors_preflight 
     head(:ok) if request.method == :options 
    end 
end 

누구를?

답변

1

마침내 문제가 발생했습니다. 여전히 혼란 스럽지만 문제의 근원지 인 내 CORS 구성이 내 Rails API에 있습니다.

내가 배운 것을 보면 Angular는 기본적으로 JSON 형식의 데이터를 전송합니다. 이것은 "Content-Type : application/json; charset = UTF-8"로 진행되는 반면, jQuery AJAX 요청은 "Content-Type : application/x-www-form-urlencoded; charset = UTF-8 "이며 $.param()을 사용하여 쿼리 문자열로 변환됩니다. 나는이 사실을 전에 들었을 지 모르지만 실제로이 사실과 그 효과를 지금까지 등록하지 않았다는 것을 인정할 것이다. 내 응용 프로그램 컨트롤러에서

, 정말처럼 내 CORS 설정을 구성 :

def set_cors_headers 
    headers['Access-Control-Allow-Origin'] = AppConfig.client['origin'] 
    headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS' 
    headers['Access-Control-Allow-Headers'] = '*' 
    headers['Access-Control-Max-Age'] = "3628800" 
end 

def cors_preflight 
    head(:ok) if request.method == :options 
end 

AppConfig 단지의 요청을 수락 할 것을 기원 내 레일 API를 알려주는 OpenStruct입니다. 그리고 다른 모든 것은 단순히 CORS 헤더를 설정하기로되어있었습니다.

여전히 확실하지 않은 이유로 (JSON 요청에서 작동하지 않음) 위의 코드는 Angular and Rails를 사용하는 자습서에서 얻었고 튜토리얼의 경우에는 수동으로 자산 파이프 라인을 제거하고 Rails에 대한 모든 것을 남겨 두었습니다. 반면 rails-api는 일부 Rails 구성을 제거합니다. 이것이 ApplicationController의 CORS 헤더 설정이 작동하지 않는 이유입니다. 이것은 로컬 호스트의 요청 받아 내 응용 프로그램을 알려줍니다

config.middleware.use Rack::Cors do 
    allow do 
     origins 'localhost:9000' 
     resource '*', :headers => :any, :methods => [:get, :post, :options, :delete] 
    end 
    end 

: 9000을, 어떤 헤더를 받아 일을 무슨 짓을

rack-cors gem을 사용하고 development.rb이 비트를 추가했다. 내 ApplicationController에서 headers['Access-Control-Allow-Headers'] = '*'을 사용하여이를 수행하고 있다고 생각했지만 생각하지 않습니다. 이러한 미들웨어 설정을 사용하도록 레일스를 지정하고 나면 모든 것이 완벽하게 작동했습니다. 내 Rails API는 이제 각도 앱에서 application/json을 수락 할 수 있습니다.

누군가 내가 아직도 혼란스러워하는 격차를 메울 수 있다면, 고맙겠습니다. 그러나 이것이 다른 사람들을 돕기를 바랍니다.

0

다음 중 하나를 보낼 수 있습니다. params 또는 : data (또는 둘 다있을 것 같습니다). https://docs.angularjs.org/api/ng/service/$http

PARAMS에서 AngularJS와 문서에 따르면 - {개체입니다.} -?의 URL 후 가 켜집니다 문자열 또는 객체의지도 키 1 = 값 1 & 키 2 = 값 2. 값 이 문자열이 아닌 경우 JSONified됩니다.

data - {string | Object} - 요청 메시지 데이터로 보낼 데이터입니다.

컨트롤러가 http-type 매개 변수/양식 데이터를 필요로하므로 params를 통해 개체를 전달하면 작동합니다. 동일한 via를 전달하는 동안 변환됩니다. 데이터는 변환되지 않기 때문에 변환되지 않습니다.

레일 컨트롤러 단에서의 데이터 포맷을 압축 해제 할 수있는 현명한 방법이 있다면 나도 몰라,하지만 당신은 $의 .PARAM (데이터) http://api.jquery.com/jQuery.param/

를 사용하여 직렬화 매개 변수로 $의 HTTP 요청에서 객체를 변환 할 수 있습니다
data: $.param($scope.your_data_object) e.g. $scope.admin 

컨트롤러에서 매개 변수 [: 데이터]의 압축을 풉니 다.