crisefd

crisefd

Hi. I’m building a rest API using Phoenix and a UI using VueJS. I have a signup endpoint in the API that returns 400 error code when requesting using my UI, but it returns 201 when using querying from postman.

This works:

curl 'http://localhost:4000/v1/users/signup' -H 'Content-Type: application/json'   --data-binary '{"user":{"email":"dummy@example.com","username":"dummy@example.com","password":"password123456"}}' 

And it fails when the UI issues the requests:

But for some reason when I check the browser devtools I see that the content-type is set to application/json for both response headers and request headers. And I don’t know how, my JS logic explicitly sets the header to ‘content-type’: ‘application/json’

Showing Posts 1 to 8

kokolegorille

kokolegorille

Hello, it’s hard to answer without code…

I am not familiar with Vue, but I don’t think it does the request by itself.

Something like fetch, or axios?

It would be nice to see how your client js code does the request to your API.

crisefd

crisefd OP

It’s a plain JS function really. All it does is call the fetch API and return the response as an observable:

export function request(method, url, payload) {
  const body = JSON.stringify(payload);
  const parameters = {
    headers: { 'Content-Type': 'application/json' } ,
    method: method,
    mode: "no-cors",
    body: body,
    cache: "default",
  };
  return Observable.create(observer => {
    fetch(url, parameters)
      .then(response => {
        observer.next(response);
        observer.complete();
      })
      .catch(error => {
        observer.error(error);
      });
  });
}

kokolegorille

kokolegorille

Those are my headers with axios…

const auth_headers = () => ({
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${AuthService.loadToken()}`,
  },
  credentials: 'same-origin',
});

My headers are a little bit different because I pass a token, but I can see I also added Accept keyword.

amnu3387

amnu3387

I think if you’re using the browser fetchAPI you need to create the headers from the constructor, I use this:

export function requester({ method, url, data, accept, content_type }, token) {
    let body = typeof data === "string" ? data : JSON.stringify(data);

    token = token ? token : "";
    content_type = content_type ? content_type : "application/json";
    accept = accept ? accept : "application/json";
    
    if (process && process.server) {
        const fetch = require("node-fetch");
        let headers = {
            "Bearer": token,
            "Content-Type": content_type,
            "Accept": accept
        };
        let request = {
            method: method,
            headers: headers,
            body: body,
            mode: "cors"
        };

        return fetch(url, request)
            .then(response => response.json())
            .catch(error => { return {error: error.message} });
        
    } else {
        
        let headers = new Headers({
            "Bearer": token,
            "Content-Type": content_type,
            "Accept": accept
        });
        
        let request = new Request(url, {
            method: method,
            headers: headers,
            body: body,
            mode: "cors"
        });
        
        return fetch(request)
            .then(response => response.json())
            .catch(error => { return {error: error.message} });
    }
}
crisefd

crisefd OP

Found the answer to my problem here. “application/json” is only a valid content type with CORS.

Now my problem is how to configure CORS in my phoenix api. I’m using cors_plug. But is not working, I’m still getting in my request.

Access to fetch at 'http://localhost:4000/v1/users/signup' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

This is my CORS config in router.ex file

defmodule DumyApiWeb.Router do
  use DummyApiWeb, :router
...
pipeline :v1 do
    plug CORSPlug, origin: "http://localhost:8080"
    plug DummyApiWeb.Version, version: :v1
end
...
scope "/v1", DummyApiWeb do
    pipe_through :v1
    post "/users/signup", UserController, :create
    post "/users/signin", UserController, :signin
  end
...
end
crisefd

crisefd OP

Solved: I had to defined an options method for UserController to make it work.

Codball

Codball

Can you elaborate? Maybe with a code example?

Exadra37

Exadra37

I would recommend you to understand the mechanics of pre-flight request, aka the one that is done with OPTIONS, and then followed by the real GET, POST, PUT or DELETE request.

A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood.

It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method , Access-Control-Request-Headers , and the Origin header.

A preflight request is automatically issued by a browser, when needed. In normal cases, front-end developers don’t need to craft such requests themselves.

Now that you are familiar with a pre-fligth request you can follow the article How to Configure CORS on your Phoenix Application to learn how to do them.

Almost every developer has faced with CORS trouble, but if you haven’t. CORS is just a http mechanism that uses specific headers to grant permission to other domains get some of your data. So imagine that you have a REST API with the domain www.outsiderhost:4000 and you have your SPA hosted in www.localhost:3000 . As you see they are not the same domain, so you have to grant access permission to www.localhost:3000 to get the data from www.outsiderhost:4000 .

— All posts loaded —

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
itzmidinesh
Hi all, I’m working on a Phoenix project where I need to make external HTTP requests and I’m trying to choose between Req and HTTPoison....
New
pragdave
How do I tell Hologram not to escape HTML when substituting into templates? {Textile.render(@product.long_description)} escapes the HTM...
New
leoschweizer
Hi, we run different LLM models across a cluster, with each node loading a configurable subset. Model-specific queues let nodes consume ...
New
rlipscombe
I’d like to create a file with 600 permissions (rw-------), but there’s a race condition if I create it and then change the permissions. ...
New
saleyn
Is there a way to import record definitions in the iex shell for pretty printing (similar to the rr command in the erl shell)? This woul...
New
rlipscombe
When I use Mix.install with a git dependency, using git@github.com:... how do I change the SSH identity used? I’ve got two Github accoun...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
raa-ziq
Hi everyone :waving_hand: I wanted to share something I’ve been building — NowBlind, a random chat app designed to help people discover ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
kip
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews