8

I have 2 parts in my app - Angular frontend and rails server. And because it's different domains, requests doesn't work by default. There are a lot of staff about that, including stack, but it doesn't works for me.

This is my method in angular controller:

$scope.test =->
  # transform = (data) ->
  #   $.param data

  $http.post('http://localhost:3000/session/create', 'token=some',
    headers:
      'Access-Control-Allow-Origin': 'http://localhost:9000',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With'
    # transformRequest: transform
  ).success (responseData) ->
    console.log(responseData)

I commented transform data, there is no difference in server response.

And I configured app (saw this in some post) like that:

.config ["$httpProvider", ($httpProvider) ->
  $httpProvider.defaults.useXDomain = true
  delete $httpProvider.defaults.headers.common["X-Requested-With"]
]

I guess that makes request not ajax like (but i'm not sure).

But there is no headers in my request. They all in some field Access-Control-Request-Headers:access-control-allow-origin, accept, access-control-allow-headers, access-control-allow-methods, content-type:

    Request URL:http://localhost:3000/session/create
    Request Method:OPTIONS
    Status Code:404 Not Found

    Request Headers

    Accept:*/*
    Accept-Encoding:gzip,deflate,sdch
    Accept-Language:en-US,en;q=0.8,ru;q=0.6
    Access-Control-Request-Headers:access-control-allow-origin, accept, access-control-allow-headers, access-control-allow-methods, content-type
    Access-Control-Request-Method:POST
    Connection:keep-alive
    DNT:1
    Host:localhost:3000
    Origin:http://localhost:9000
    Referer:http://localhost:9000/
    User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.8 Safari/537.36

    Response Headers

    Content-Length:12365
    Content-Type:text/html; charset=utf-8
    X-Request-Id:2cf4b37b-eb47-432a-ab30-b802b3e33218
    X-Runtime:0.030128

Chrome console:

OPTIONS http://localhost:3000/session/create 404 (Not Found) angular.js:6730
OPTIONS http://localhost:3000/session/create No 'Access-Control-Allow-Origin' header is     present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. angular.js:6730
XMLHttpRequest cannot load http://localhost:3000/session/create. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. localhost/:1

Other insignificant information: On the server:

class ApplicationController < ActionController::Base
  before_filter :allow_cross_domain_access

  protected

  def allow_cross_domain_access
    headers['Access-Control-Allow-Origin'] = '*'# http://localhost:9000
    headers['Access-Control-Allow-Headers'] = 'GET, POST, PUT, DELETE'
    headers['Access-Control-Allow-Methods'] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(',')
    headers['Access-Control-Max-Age'] = '1728000'

  end
end

Routes is obvious post "session/create". And session controller:

class SessionController < ApplicationController
  respond_to :json, :html, :js

  def create
    respond_with "logged in"
    # render nothing: true
  end
end

I use latest version of angular 1.2.0.rc-2. this is my project on github

zishe
  • 10,665
  • 12
  • 64
  • 103
  • 1
    The headers must not be being set correctly, are you using another webserver to forward requests to a rails app server? – Slicedpan Oct 08 '13 at 12:54
  • I generated app with yeoman angular-generator. It based on grunt perhaps there is some node.js server. Do you think it can change my requests? – zishe Oct 08 '13 at 12:57
  • The first request gets a 404 response. Can you post the output of rake routes? (alternatively go to http://localhost:3000/nonexistent_page in your browser) – Slicedpan Oct 08 '13 at 13:35
  • Routes is fine - i changes post on get and `respond_with "logged in"` on `render nothing: true`, and it shows empty page without any errors. – zishe Oct 08 '13 at 13:50
  • 1
    It won't respond to OPTIONS though, this is necessary for the preflight requests. – Slicedpan Oct 08 '13 at 14:09
  • I've add it before, just change in post, not helped. By the way, I tried https://github.com/cyu/rack-cors this gem, same result. The issue in frontend part i think. – zishe Oct 08 '13 at 14:14
  • 1
    The frontend part is making an OPTIONS request (correctly), the server is responding with 404 (most probably not correct). That is what leads me to believe that the server is the issue. – Slicedpan Oct 08 '13 at 14:25
  • Perhaps i should make request to open api and check response. – zishe Oct 08 '13 at 14:38
  • You were right too, thanks for help. – zishe Oct 08 '13 at 14:42

1 Answers1

7

You mix up the request and response headers in your example.

When doing a cross domain request (CORS) and you want to make anything different than a plain GET - so for example a POST or adding custom headers - the browser will first make an OPTIONS request. This is what you see in your developer console:

OPTIONS http://localhost:3000/session/create 404 (Not Found) angular.js:6730

The server then should add the appropriate headers to the response of the OPTIONS request.

So you can remove the custom headers from the Angular call. Next you need to make sure that your server/application answers the OPTIONS request, not returning a 404.

Thomas
  • 11,272
  • 2
  • 24
  • 40
  • I do this `$http(method: 'OPTIONS', url: 'http://localhost:3000/session/create').success (responseData) -> console.log(responseData)` and add to routes `options "session/create"` and console now shows `OPTIONS http://localhost:3000/session/create 500 (Internal Server Error) ` and the same next lines. – zishe Oct 08 '13 at 14:22
  • Yes, you are right, i remove those header lines, and it works now. I guess before there is a problem on rails side, and doesn't work by other reason. Thanks. – zishe Oct 08 '13 at 14:41