How to add “Access-Control-Allow-Origin” headers t

2020-05-01 10:27发布

I'm interviewing for a front-end developer job and have been given a coding test to build a simple front-end interface. I've been given the server, which has been written in Ruby (2.1.3) and has 3 endpoints which I am to make use of in my front-end client. I have no experience whatsoever with Ruby but I followed their instructions for setting up the server and it seems to work - I get responses from all the endpoints. The problem is that I'm not getting any response from my client app, which is in a different "domain" (actually, they're both just different ports of localhost). It seems that they are not setting the "Access-Control-Allow-Origin" headers on the API, but I don't want to go back to them asking how to fix this because I'm afraid it will reflect poorly on my test.

Below is the server file structure and I've also included the contents of a few files which seem to be relevant. If anyone wants to see other files, please just comment. I'm sure this is simple for anyone who knows Ruby but I haven't the foggiest clue.

D:.
¦   .gitkeep
¦   client.rb
¦   config.ru
¦   foo.sqlite3
¦   Gemfile
¦   Gemfile.lock
¦   Rakefile
¦   README.md
¦
+---app
¦   +---controllers
¦   ¦       api_controller.rb
¦   ¦       application_controller.rb
¦   ¦       not_found_controller.rb
¦   ¦       payments_controller.rb
¦   ¦
¦   +---models
¦   ¦       payment.rb
¦   ¦
¦   +---views
¦           booking.html
¦           confirmation.html
¦
+---config
¦       boot.rb
¦       dispatcher.rb
¦
+---db
¦   ¦   schema.rb
¦   ¦   seeds.rb
¦   ¦
¦   +---migrate
¦           20150331094122_create_payments.rb
¦
+---lib
¦       my_application.rb
¦
+---log
¦       development.log
¦       test.log
¦
+---public
¦   ¦   404.html
¦   ¦   500.html
¦   ¦
¦   +---css
¦           style.css
¦
+---script
¦       console
¦       server
¦
+---spec
¦   ¦   spec_helper.rb
¦   ¦
¦   +---acceptance
¦   ¦       api_endpoint_spec.rb
¦   ¦       not_found_spec.rb
¦   ¦
¦   +---models
¦           payment_spec.rb
¦
+---vendor
    +---libs
            foobar_goodies

boot.rb

ENV['RACK_ENV'] ||= 'development'

# Bundler
require 'bundler/setup'
Bundler.require :default, ENV['RACK_ENV'].to_sym

require_relative '../lib/my_application.rb'

root_path = MyApplication.root
lib_path = File.join(MyApplication.root, 'lib')
app_path = File.join(MyApplication.root, 'app')
[root_path, lib_path, app_path].each { |path| $LOAD_PATH.unshift(path) }

ENV['PEERTRANSFER_ROOT'] = root_path

require 'config/dispatcher'
require 'sinatra/activerecord'

set :database, { adapter: "sqlite3", database: "foo.sqlite3" }

require 'app/models/payment'

my_application.rb

module MyApplication
  class << self
    def root
      File.dirname(__FILE__) + '/..'
    end

    def views_path
      root + '/app/views'
    end

    def public_folder
      root + '/public'
    end
  end
end

dispatcher.rb

require 'controllers/application_controller'
require 'controllers/not_found_controller'

require 'controllers/api_controller'
require 'controllers/payments_controller'

module MyApplication
  class Dispatcher
    def call(env)
      path_info = env['PATH_INFO']

      app = case path_info
        when %r{^/api} then ApiController.new
        when %r{^/payment} then PaymentsController.new
        else NotFoundController.new
      end

      app.call(env)
    end
  end
end

application_controller.rb

class ApplicationController < Sinatra::Base
  set :views, MyApplication.views_path
  set :public_folder, MyApplication.public_folder

  not_found do
    html_path = File.join(settings.public_folder, '404.html')
    File.read(html_path)
  end

  error do
    raise request.env['sinatra.error'] if self.class.test?

    File.read(File.join(settings.public_folder, '500.html'))
  end
end

api_endpoint_spec.rb

require 'spec_helper'
require 'models/payment'

describe 'API Endpoint' do
  it 'responds with a JSON welcoming message' do
    get '/api'

    expect(last_response.status).to eq(200)
    expect(last_response.body).to eq('{"message":"Hello Developer"}')
  end

  it 'returns all the stored payments' do
    Payment.all.map(&:delete)
    Payment.new(reference: 'any reference', amount: 10000).save

    get '/api/bookings'

    expect(last_response.status).to eq(200)
    expect(last_response.body).to eq("{\"bookings\":[{\"reference\":\"any reference\",\"amount\":10000,\"country_from\":null,\"sender_full_name\":null,\"sender_address\":null,\"school\":null,\"currency_from\":null,\"student_id\":null,\"email\":null}]}")
  end

  def app
    MyApplication::Dispatcher.new
  end
end

标签: ruby sinatra
1条回答
The star\"
2楼-- · 2020-05-01 11:10

Sinatra is a simple and lightweight web server. The general idea is that you write response routes like this:

get '/api' do
 "Hello world"
end

When you make a HTTP GET request to yoursite.com/api you will get a "Hello world" as response.

Now to add the header you want, this should do the trick:

get '/api' do
  response['Access-Control-Allow-Origin'] = '*'
  "Hello world"
end
查看更多
登录 后发表回答