简体   繁体   中英

Using Rails, how should I configure my application.rb in order to allow for CORS requests to take place?

I am using Rails as a backend API to support a frontend that is made with VueJS. I want to send a POST request from VueJS when a button is pressed on the website, I have used axios to do this
`

methods: {
    // Performs a POST request to the rails endpoint and passes the email and pass as parameters
        signup() {
          if (this.password === this.password_confirmation) {
            this.$http.plain
              .post("/signup", {
                email: this.email,
                password: this.password,
                password_confirmation: this.password_confirmation
              })
              // If successful execute signinSuccesful
              .then(response => this.signinSuccesful(response))
              // If it doesn't run for whatever reason, execute signupFailed
              .catch(error => this.signinFailed(error));
          }
      },`

This should in theory create a POST request that would be received by the API, I have attempted to catch the request like this: post "signup", controller: :signup, action: :create

However, when I look in the console on chrome I get an error when I first load the site:

`0/signin net::ERR_CONNECTION_REFUSED`

And another error when I click the button to send the POST request: *

Access to XMLHttpRequest at ' http://localhost:3000/signup ' from origin ' http://localhost:8080 ' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

My 'application.rb' file looks like this:

`module RecordstoreBackend
     class Application < Rails::Application
        # Initialize configuration defaults for originally generated Rails version.
        config.load_defaults 6.0
        config.api_only = true

        config.middleware.insert_before 0, Rack::Cors do
          allow do
            origins '*'
            resource '*', headers: :any, methods: [:get, :patch, :put, :delete, :post, :options]
          end
        end`

I think the issue is this file, but I am not sure how to configure it. Thanks for your help.

It seems to me like you're missing the host for that request (on your Vue app). Notice the error says 0/signup which indicates that it's sending the request to http://0/signup that is, in turn, "rejecting" the connection.

I'm not familiar with Vue.js structure, but I'd recommend encapsulating the axios call on a plugin that would use the host from an environment configuration file, so that you can have different hosts for localhost and your production env. Or even just add the host to your environment:

methods: {
    // Performs a POST request to the rails endpoint and passes the email and pass as parameters
        signup() {
          if (this.password === this.password_confirmation) {
            this.$http.plain
              .post(`${process.env.API_HOST}/signup`, {
                email: this.email,
                password: this.password,
                password_confirmation: this.password_confirmation
              })
              // If successful execute signinSuccesful
              .then(response => this.signinSuccesful(response))
              // If it doesn't run for whatever reason, execute signupFailed
              .catch(error => this.signinFailed(error));
          }
      },

Reference: https://cli.vuejs.org/guide/mode-and-env.html#environment-variables

If you want to fix it the way you have it now, simply add your host to the axios call:

methods: {
    // Performs a POST request to the rails endpoint and passes the email and pass as parameters
        signup() {
          if (this.password === this.password_confirmation) {
            this.$http.plain
              .post("http://localhost:3000/signup", {
                email: this.email,
                password: this.password,
                password_confirmation: this.password_confirmation
              })
              // If successful execute signinSuccesful
              .then(response => this.signinSuccesful(response))
              // If it doesn't run for whatever reason, execute signupFailed
              .catch(error => this.signinFailed(error));
          }
      },

About the CORS error, check this: https://stackoverflow.com/a/25727411/715444

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