Localhost has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status

Viewed 6308

So I am working on my first Vue project and I came across a problem that I can't seem to solve.

I am trying to perform CRUD operations with Vue and my backend RESTful API service, but I keep getting this error:

Access to XMLHttpRequest at 'http://localhost:8080/parties/3' from origin 'http://localhost:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

When i was searching for the answer I came across this:

header := w.Header()
header.Add("Access-Control-Allow-Origin", "*")
header.Add("Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS")
header.Add("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")

And I believe this is in the right direction of the answer, but I don't really know where to put in my code (I think it probably will have to go into the script of the Vue page, but I am not really sure)

This is my Vue page:

<template>
  <div v-if="currentParty" class="edit-form">
    <h4>Party</h4>
    <form>
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name"
               v-model="currentParty.name"
        />
      </div>
      <div class="form-group">
        <label for="description">Description</label>
        <input type="text" class="form-control" id="description"
               v-model="currentParty.description"
        />
      </div>

      <div class="form-group">
        <label><strong>Status:</strong></label>
        {{ currentParty.isPartyNational ? "isPartyNational" : "Pending" }}
      </div>
    </form>

    <button class="badge badge-primary mr-2"
            v-if="currentParty.isPartyNational"
            @click="updatePublished(false)"
    >
      UnPublish
    </button>
    <button v-else class="badge badge-primary mr-2"
            @click="updatePublished(true)"
    >
      Publish
    </button>

    <button class="badge badge-danger mr-2"
            @click="deleteParty"
    >
      Delete
    </button>

    <button type="submit" class="badge badge-success"
            @click="updateParty"
    >
      Update
    </button>
    <p>{{ message }}</p>
  </div>

  <div v-else>
    <br />
    <p>Please click on a Party...</p>
  </div>
</template>

<script>
import PartyDataService from "@/services/PartyDataService";

export default {
  name: "Party",
  data() {
    return {
      currentParty: null,
      message: ''
    };
  },
  methods: {
    getParty(id) {
      PartyDataService.get(id)
          .then(response => {
            this.currentParty = response.data;
            console.log(response.data);
          })
          .catch(e => {
            console.log(e);
          });
    },
    updatePublished(status) {
      var data = {
        id: this.currentParty.id,
        name: this.currentParty.name,
        description: this.currentParty.description,
        published: status
      };

      PartyDataService.update(this.currentParty.id, data)
          .then(response => {
            this.currentParty.published = status;
            console.log(response.data);
          })
          .catch(e => {
            console.log(e);
          });
    },
    updateParty() {
      PartyDataService.update(this.currentParty.id, this.currentParty)
          .then(response => {
            console.log(response.data);
            this.message = 'The Party was updated successfully!';
          })
          .catch(e => {
            console.log(e);
          });
    },
    deleteParty() {
      PartyDataService.delete(this.currentParty.id)
          .then(response => {
            console.log(response.data);
            this.$router.push({ name: "parties" });
          })
          .catch(e => {
            console.log(e);
          });
    }
  },
  mounted() {
    this.message = '';
    this.getParty(this.$route.params.id);
  }
};
</script>

<style>
.edit-form {
  max-width: 300px;
  margin: auto;
}
</style>

And this is my PartyDataService in case you need it:

import http from "../http-common";

class PartyDataService {
    getAll() {
        return http.get("/parties");
    }

    get(id) {
        return http.get(`/parties/${id}`);
    }

    create(data) {
        return http.post("/parties/", data);
    }

    update(id, data) {
        return http.put(`/parties/${id}`, data);
    }

    delete(id) {
        return http.delete(`/parties/${id}`);
    }

    deleteAll() {
        return http.delete(`/parties`);
    }
    findByTitle(title){
        return http.get(`/tutorials?title=${title}`)
    }
}

export default new PartyDataService();

After some more research I think this file is important to upload: My http-common.js:

import axios from "axios";

export default axios.create({
    baseURL: "http://localhost:8080/",
    headers: {
        "Content-type": "application/json",

    }

});

Adding this to the code above in headers:

'Access-Control-Allow-Origin' : '*',
 "Access-Control-Allow-Methods":"GET,PUT,POST,DELETE,PATCH,OPTIONS"

Does not work. It only makes another working get operation on another Vue page in my project not work anymore.

Extra info:

  • I am already using an access-control-allow-origin extension (in case it is information you need)
  • My backend RESTful API is made with Spring boot (gradle)
  • I am just learning about Vue and stuff, so could you explain your answer as simple as possible?

If you need extra files or information you can ask me and I will add it into the post.

Thanks in advance!

1 Answers

Cors is a mechanism in browsers to make sure that your application is allowed to use that API (definition can be a little bit wrong but it boils down to that). Which means that your server must send the headers described in your answer:

header := w.Header()
header.Add("Access-Control-Allow-Origin", "*")
header.Add("Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS")
header.Add("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")

Your client (vuejs application) doesn't need to do anything related to CORS. It is your backend server that needs to send these headers.

In your question you do not have the backend server you are using (Laravel, express, spring, etc...) so it is hard to guide you to the right direction without knowing you backend technologies

Related