简体   繁体   中英

CORS issue on Angular2 app to Rails5 Back-end

I've been struggling with CORS as long as I can remember, but I'm trying a very simple thing: 3 Micro-services on C9 - All 3 diff ports so not same origination.

In Rails:

Program A-cors.rb -Does not work

Rails.application.config.middleware.insert_before 0, Rack::Cors do
    allow do
     origins '*'

     resource '*',
       headers: :any,
       methods: [:get, :post, :put, :patch, :delete, :options, :head]
    end
end

Program B - cors.rb Does Work

Rails.application.config.middleware.insert_before 0, Rack::Cors do
    allow do
     origins '*'

     resource '*',
       headers: :any,
       methods: [:get, :post, :put, :patch, :delete, :options, :head]
    end
end

The Angular2 Service is also VERY similar for both (Only names change) so I will only show

Program As - service

import { Injectable } from '@angular/core'
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';

import { Document } from './document';

@Injectable()
export class DocumentService{
    private documentsUrl = "//freeland-camp-documents-dnorthrup.c9users.io/freelance_documents.json";

    constructor(
        private http: Http    
    ) {}

    getDocuments(): Observable<Document[]> {
        let headers = new Headers({ 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
        let options = new RequestOptions({ headers: headers });
        return this.http.get(this.documentsUrl)
                        .map((response: Response) => <Document[]>response.json())
                        .catch(this.handleError);
    }

    private handleError (error: Response | any) {
        // In a real world app, we might use a remote logging infrastructure
        let errMsg: string;
        if (error instanceof Response) {
          const body = error.json() || '';
          const err = body.error || JSON.stringify(body);
          errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
          errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }
}

The let headers are the most recent change I tried to make, after reading another article. From what I understand about CORS it's Rails that's prohibiting this, however, everytime the call is made from Angular I see

Started GET "/freelance_documents.json" for 108.51.108.71 at 2017-03-04 23:46:38 +0000
Processing by FreelanceDocumentsController#index as JSON
  FreelanceDocument Load (0.5ms)  SELECT "freelance_documents".* FROM "freelance_documents" ORDER BY created_at DESC
Completed 200 OK in 8ms (Views: 6.5ms | ActiveRecord: 0.5ms)

In the console - As if Rails thinks it happened successfully (I assume it's because Rails is in API mode and the JSON always renders?

What exactly am I missing? Program B originally had the true origin URL in there and still worked, changing it to * didn't resolve anything.

Per the Rails5 Article I found I also placed:

config.action_dispatch.default_headers = {
  'Access-Control-Allow-Origin' => 'freeland-camp-documents-dnorthrup.c9users.io:8082',
  'Access-Control-Request-Method' => %w{GET POST OPTIONS}.join(",")
}

in Application.rb to no avail. Welcome any insight - I'm out of ideas. I tried Chrome's Plugin to bypass Headers (Not effective) and caused Program A to work but broke Program B saying "origin evil.com not sufficient". - This was when I didn't have just *.

Welcome any input.

For those who encounter this:

I was able to resolve my issue by modifying config/application.rb and including:

config.action_dispatch.default_headers = {
  'Access-Control-Allow-Origin' => '*',
  'Access-Control-Request-Method' => %w{GET POST OPTIONS}.join(",")
}

was the correct solution - It seems I had a bit of a cache issue. I didn't use * for Origin, but the exact domain that is calling it.

In the end I needed BOTH the cors.rb to have:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
    allow do
     origins '*'

     resource '*',
       headers: :any,
       methods: [:get, :post, :put, :patch, :delete, :options, :head]
    end
end

and application.rb to have

config.action_dispatch.default_headers = {
  'Access-Control-Allow-Origin' => '*',
  'Access-Control-Request-Method' => %w{GET POST OPTIONS}.join(",")
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM