0

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.

S4boteur
  • 135
  • 2
  • 12
  • Possible duplicate of [Response to preflight request doesn't pass access control check](https://stackoverflow.com/questions/35588699/response-to-preflight-request-doesnt-pass-access-control-check) – Sasa Blagojevic Jun 01 '19 at 21:39

2 Answers2

1

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.

Community
  • 1
  • 1
Daniel
  • 8,788
  • 11
  • 33
  • 68
  • I'm only using one Laravel based site, my requests doesnt go outside of application. I'm simply posting data to controller and retrive validation message if something is wrong otherwise simply reload page. – S4boteur Jun 01 '19 at 17:53
  • In that case you can update the `action` property on the form with id formRegister so that it points to the https version of your site – Daniel Jun 01 '19 at 18:52
0

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]);
                            }
                        }
                    }
                });
        });