简体   繁体   中英

Access to XMLHttpRequest has been blocked by CORS policy. No 'Access-Control-Allow-Origin' header is present on the requested resource

When I try to send an email trough an api, i get this message:

Access to XMLHttpRequest at ' https://api.urosciric.com/mail ' from origin ' https://urosciric.com ' 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.

I've seen many solutions of which none are the same and none of them worked so far.

Angular code:

    const httpOptions = {
      headers: new HttpHeaders({
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
      })
    };

    this.http.post('https://api.urosciric.com/mail',
      { firstName: this.FirstName, lastName: this.LastName, email: this.Email, phone: this.Phone, text: this.Text },
      httpOptions)
      .pipe(catchError(err => {
        this.onMailSend(false);
        return throwError(err);
      })).subscribe(data => {
        this.onMailSend(true);
        return data;
      });

Laravel (api) code:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;

use App\Mail\General;

class MailController extends Controller
{
    public function send(Request $request){

            $firstName = $request -> input('firstName');
            $lastName = $request -> input('lastName');
            $email = $request -> input('email');
            $text = $request -> input('text');
            $phone = $request -> input('phone');

            $to = "ciricbgd@gmail.com";
            $subject = "[urosciric.com] email from ".$firstName." ".$lastName;
            $txt = $text;
            $headers = "From: mail@urosciric.com";

            mail($to,$subject,$txt,$headers);

            return response()->json('Mail sent. Thank you!', 201); 

        return response()->json('Mail not sent. Please try contacting me directly at ciricbgd@gmail.com',400);
    }
}

When i try in development or prod mode, I get this error, but when I use postman or api testing software, everything works fine.

Firstly, You have to understand for the CORS policy response to handle the request, the backend/API is always responsible. So any addition to your Angular frontend would not help .

Secondly, in the simple words, most browsers has CORS policy to enforce preventing issues related to CSRF attacks . so, If you access with Incognito Mode it will not give you CORS error. In addition, when you are using POSTMAN or other API testing software they are simply Developer Tools , not browsers, so they don't care about CORS .

As for the solution, you need to create a Global Middleware to handle this CORS issue.

If you are using Laravel API MicroFramework Lumen -

Middleware handle() :

public function handle($request, \Closure $next)
{
    $headers = [
        'Access-Control-Allow-Origin'      => '*',
        'Access-Control-Allow-Methods'     => 'GET, POST, PUT, PATCH, OPTIONS, DELETE',
        'Access-Control-Allow-Headers'     => 'Accept, Content-Type, Origin, Authorization, X-Requested-With, Content-Language, Subject'
    ];

    if ($request->isMethod('OPTIONS'))
    {
        return response()->json('{"method":"OPTIONS"}', 200, $headers);
    }

    $response = $next($request);

    foreach($headers as $key => $value)
    {
        $response->header($key, $value);
    }

    return $response;
}

Then, register this middleware in bootstrap/app.php to work:

$app->middleware([
   ...
   App\Http\Middleware\CorsMiddleware::class,
]);

So when any requests comes to your API it will pass through this middleware and will be verified as a valid request.

you need to create a proxy.conf.json file and add these properties to it

{
"/": {
                "target": "http://api.urosciric.com/mail",
                "secure": false,
                "logLevel": "debug"
  }
}

then you have to addd this file to angular.json under options with it's path like so

"serve": {
 "options": {
        "browserTarget": "app:build",
        "proxyConfig": "src/proxy.conf.json"
      },
   }

that's worked for me hopes it work with you

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.

Related Question Access to XMLHttpRequest from origin has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource localhost:4200 has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource Angular 13 : has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource Angular7 : has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource Access to XMLHttpRequest at .' from origin . has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present No 'Access-Control-Allow-Origin' header is present on the requested resource. Access to XMLHttpRequest has been blocked by CORS plicy 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource Angular Socketio nodejs - blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource keycloak-angular: Blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource Angular/Spring with cors mapping added - blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM