S4boteur
S4boteur

Reputation: 145

Laravel Ajax request, No 'Access-Control-Allow-Origin' header

Today i extended my workflow with Heroku and when i got everything up and running and started testing things like registration/login modal, then i got this error to my console.

Access to XMLHttpRequest at 'http://app-name.herokuapp.com/register' from origin 'https://app-name.herokuapp.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.

Tried adding Content-Security-Policy to my header in layout file, also adding X-CSRF-TOKEN to my ajax request header removed some part of the error, but then is just googled different solutions and tried them.

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
 $(document).on('submit', '#formRegister', function(e) {
            e.preventDefault();

            $('input+small').text('');
            $('#formRegister input').removeClass('is-invalid');

            $.ajax({
                method: $(this).attr('method'),
                url: $(this).attr('action'),
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
                    'Access-Control-Allow-Methods' : 'POST',
                    'Access-Control-Allow-Headers' : 'X-Requested-With, Content-Type, X-Auth-Token, Origin, Authorization'
                },
                data: $(this).serialize(),
                dataType: "json",
                crossDomain: false
            })
                .done(function(data) {
                    $('.success-registered').removeClass('d-none');
                    $('#formRegister input').val('');
                    setTimeout(function() {
                        $('.success-registered').addClass('d-none');
                        location.reload();
                    }, 3000);
                    $('#login').modal('hide');
                })
                .fail(function(data) {
                    if (data.status === 422 && data.responseJSON) {
                        if (Object.keys(data.responseJSON.errors).length) {
                            for (field in data.responseJSON.errors) {
                                var error = data.responseJSON.errors[field];
                                var input = '#formRegister input[name=' + field + ']';
                                $(input).addClass('is-invalid');
                                $(input).next('span').find('strong').text(error[0]);
                            }
                        }
                    }
                });
        });
public function register(Request $request)
    {
        $this->validator($request->all())->validate();

        event(new Registered($user = $this->create($request->all())));

        $this->guard()->login($user);

        return $this->registered($request, $user)
            ?: response()->json();
    }
 protected function sendLoginResponse(Request $request)
    {
        $request->session()->regenerate();

        $this->clearLoginAttempts($request);

        return $this->authenticated($request, $this->guard()->user())
            ?: response()->json();
    }

I except JSON output for my validation and page reload on successful request from the controller.

Upvotes: 0

Views: 7284

Answers (2)

Natvarsinh Parmar - bapu
Natvarsinh Parmar - bapu

Reputation: 1138

In header:

<meta name="csrf-token" content="{{ csrf_token() }}" />

Add csrf field in form

<form action="your action" method="post">
  @csrf

  <!-- your other fields -->
</form>

In js code:

$(document).on('submit', '#formRegister', function(e) {
            e.preventDefault();

            $('input+small').text('');
            $('#formRegister input').removeClass('is-invalid');

            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });

            $.ajax({
                method: $(this).attr('method'),
                url: $(this).attr('action'),                
                data: $(this).serialize(),
                dataType: "json",
                cache: false,
                crossDomain: false
            })
                .done(function(data) {
                    $('.success-registered').removeClass('d-none');
                    $('#formRegister input').val('');
                    setTimeout(function() {
                        $('.success-registered').addClass('d-none');
                        location.reload();
                    }, 3000);
                    $('#login').modal('hide');
                })
                .fail(function(data) {
                    if (data.status === 422 && data.responseJSON) {
                        if (Object.keys(data.responseJSON.errors).length) {
                            for (field in data.responseJSON.errors) {
                                var error = data.responseJSON.errors[field];
                                var input = '#formRegister input[name=' + field + ']';
                                $(input).addClass('is-invalid');
                                $(input).next('span').find('strong').text(error[0]);
                            }
                        }
                    }
                });
        });

Upvotes: 0

Daniel
Daniel

Reputation: 11182

Your sites have different protocols. One uses http and the other https. According to MDN:

A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.

Cross-Origin Resource Sharing

To fix this, use the same protocol for both sites.

Upvotes: 1

Related Questions