Failed to send CORS request.

I built an API with SLIM Micro-Framework. I am setting up some middleware that adds CORS headers using the following code.

class Cors{

    public function __invoke(Request $request, Response $response, $next){

        $response = $next($request, $response);
        return $response
            ->withHeader('Access-Control-Allow-Origin', 'http://mysite')
            ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
            ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    }

}

For my front-end, I used VueJS. I configure VueResource and create a function with the following code.

register (context, email, password) {
  Vue.http({
    url: 'api/auth/register',
    method: 'POST',
    data: {
    email: email,
    password: password
  }
}).then(response => {
  context.success = true
}, response => {
  context.response = response.data
  context.error = true
})
}

In chrome, the following error is logged to the console.

XMLHttpRequest cannot load http://mysite:9800/api/auth/register. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mysite' is therefore not allowed access.

Oddly enough, GET requests work just fine.

+4
source share
4 answers

You get half 1/2 of the solution here.

What you are missing is the OPTIONS route to which these headers need to be added.

$app->options('/{routes:.+}', function ($request, $response, $args) {
    return $response
        ->withHeader('Access-Control-Allow-Origin', 'http://mysite')
        ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
        ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
});
+2
source

In fact, CORS is implemented at the browser level. and even with

 return $response
            ->withHeader('Access-Control-Allow-Origin', 'http://mysite')
            ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
            ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

chrome Mozilla , . , .

CORS

​​ Chrome

+2

- , OPTIONS. , .

, Slim framework, Symfony.

:

// Headers allowed to be returned.
const ALLOWED_HEADERS = ['Authorization', 'Origin', 'Content-Type', 'Content-Length', 'Accept'];

onKernelRequest, :

    /**
     * @param GetResponseEvent $event
     */
    public function onKernelRequest(GetResponseEvent $event)
    {
        // Don't do anything if it not the master request
        if (!$event->isMasterRequest()) {
            return;
        }

        // Catch all pre-request events
        if ($event->getRequest()->isMethod('OPTIONS')) {
            $router = $this->container->get('router');
            $pathInfo = $event->getRequest()->getPathInfo();

            $response = new Response();
            $response->headers->set('Access-Control-Allow-Origin', $event->getRequest()->headers->get('Origin'));
            $response->headers->set('Access-Control-Allow-Methods', $this->getAllowedMethods($router, $pathInfo));
            $response->headers->set('Access-Control-Allow-Headers', implode(', ', self::ALLOWED_HEADERS));
            $response->headers->set('Access-Control-Expose-Headers', implode(', ', self::ALLOWED_HEADERS));
            $response->headers->set('Access-Control-Allow-Credentials', 'true');
            $response->headers->set('Access-Control-Max-Age', 60 * 60 * 24);
            $response->send();
        }
    }

Origin ( , , ). , .

+1

CORS . , , Vue, , , http . .

const data = {
    email: email,
    password: password
  } 
const options = {
    headers: {
        'Access-Control-Expose-Headers': // all of your headers,
        'Access-Control-Allow-Origin': '*'
    }
}
Vue.http.post('api/auth/register', JSON.stringify(data), options).then(response => {
    // success
}, response => {
    // error
})

, , , Access-Control-Allow-Origin. , , , , .

Vue.http.headers.common['Access-Control-Expose-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, x-session-token, timeout, Content-Length, location, *'
Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'
+1

All Articles