0

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.

UC3D
  • 383
  • 1
  • 3
  • 10
  • Does this answer your question? [XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header](https://stackoverflow.com/questions/35553500/xmlhttprequest-cannot-load-xxx-no-access-control-allow-origin-header) – Quentin Apr 03 '20 at 14:32

2 Answers2

1

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.

Fahim Uddin
  • 681
  • 2
  • 10
  • 36
0

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

AbouLkhair
  • 175
  • 3
  • 16