Before a fetch
is sent, the browser will send a request method OPTIONS
to confirm that the API will accept the request from a script with a particular origin.
Chrome shows that the my Axum server is rejecting my client's request with 405. My router looks something like this:
let app = Router::new()
.layer(TraceLayer::new_for_http())
.layer(CorsLayer::permissive())
.route("/api", post(server));
Router::layer says All requests to the router will be processed by the layer’s corresponding middleware. but I'm not sure its doing its job.
The
.layer()
function is a builder so returns a newRouter
, with the inner routers wrapped. The route/api
will be tested first and be rejected 405 because only request methodPOST
is supported - notOPTIONS
.In summary, you need your
CorsLayer
"outside" your route so it can answerOPTIONS
requests.Note the example in the documentation:
By the way, your
TraceLayer
is not tracing your API calls for the same reason!Try this, and you'll see the
OPTIONS
request logged, and thePOST
should hit yourserver
: