Angular2应用程序到Rails5后端的CORS问题

时间:2017-03-04 23:49:07

标签: ruby-on-rails angularjs cors ruby-on-rails-5

只要我记得,我就一直在努力与CORS斗争,但我尝试了一个非常简单的事情:3 C9上的微服务 - 所有3个差异端口所以起源不同。

在Rails中:

Program A-cors.rb - 不起作用

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 有效吗

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

Angular2服务对于两者都非常相似(仅更改名称)所以我只会显示

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

在阅读另一篇文章之后,let headers是我尝试做的最新变化。根据我对CORS的理解,Rails禁止这样做,但每次调用Angular时我都会看到

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)

在控制台中 - 好像Rails认为它成功发生了(我假设它是因为Rails处于API模式并且JSON总是呈现?

我到底错过了什么?程序B最初在那里有真正的原始URL并且仍然有效,将其更改为*并未解决任何问题。

根据Rails5文章,我发现我也放置了:

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(",")
}
在Application.rb中

无济于事。欢迎任何见解 - 我没有想法。我尝试使用Chrome插件来绕过标题(效果不佳)并导致Program A工作,但打破Program B说&#34;起源evil.com不够&#34;。 - 那时我还没有*。

欢迎任何输入。

1 个答案:

答案 0 :(得分:0)

对于遇到此事的人:

我能够通过修改来解决我的问题 function deepIncludes (object) { return Object.keys(object).some(k => { let v = object[k] return (v && typeof v == 'object') ? deepIncludes.call(this, v) : String(v).includes(this) }) } let array = [ { name: 'Jane Smith', address: '123 Main St, Boston, MA 01234', telephone: { primary: '1234567890', secondary: '1112223333' } }, { name: 'John Smith', address: '333 Main St, New York, NY 56789', telephone: { primary: '2223334444', secondary: '3334445555' } } ] // Usage: console.log( array.filter(deepIncludes, '3334445555') //=> [ { name: 'John Smith', ... } ] )并包括:

config/application.rb

是正确的解决方案 - 似乎我有一些缓存问题。 我没有使用*作为Origin,而是使用调用它的确切域名。

最后我需要config.action_dispatch.default_headers = { 'Access-Control-Allow-Origin' => '*', 'Access-Control-Request-Method' => %w{GET POST OPTIONS}.join(",") } 同时拥有:

cors.rb

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

application.rb