简体   繁体   中英

Laravel5 AJAX set cookie not working

Could you give me advice please?

I'm saving in COOKIES some data. I create method for this in Laravel, so I call ajax on this method to set cookie but when I try to call next request where I access this cookie value, it is not saved and I can access it in second request... I don't know why... it's quite strange :/

I have this code:

public function setCookie: method in laravel controller to set cookie
var setCookie: function in javascript where I call ajax request to set cookie
var loadEvents: method called after ajax call where I set cookie.


public function setCookie(Request $request) {

    $cookieName = $request->input('cookie_name');
    $cookieVal = $request->input('cookie_val');

    return response()->json(['status' => 'success'])->withCookie(cookie($cookieName, $cookieVal));
}


var setCookie = function (cookieName, cookieVal) {
    $.ajax({
        type: 'POST',
        url: window.setCookieUrl,
        data: {
            cookie_name: cookieName,
            cookie_val: cookieVal,
            _token: getCsrfToken()
        }
    }).done();
};



public function loadEvents(Request $request) {

    $activeCalendarsIds = $request->input('active_calendars_ids');
    if($activeCalendarsIds == null)
        $activeCalendarsIds = Cookie::get('adminActiveCalendars');


    $eventsPage = $this->getPostParam('page');
    $eventsLimit = $this->getPostParam('limit');

    $this->service->setFilter('page', $eventsPage);
    $this->service->setFilter('limit', $eventsLimit);

    $events = $this->service->getCalendarsEvents($activeCalendarsIds);
    $eventList = view('admin/calendar/event_list', ['events' => $events]);

    return response()->json([
        'status' => 'success',
        'data' => '' . $eventList . ''
    ]);

}

Update: the following works as expected. It seems there's a mixup in the order the requests are stated. The setCookie ajax request must be finished before any loadEvent ajax request is sent.

Controller actions:

public function set(Request $request)
{
    $cookieName = $request->input('cookie_name');
    $cookieVal = $request->input('cookie_val');
    return response()->json(['previousCookieValue' => Cookie::get('adminActiveCalendars')])->withCookie(cookie($cookieName, $cookieVal));
}

public function events() {
    return response()->json([
        'cookieValue' => Cookie::get('adminActiveCalendars'),
    ]);
}

Javascript/jQuery:

var setCookie = function(cookieName, cookieVal) {
  console.log('Set cookie', cookieName, cookieVal);
  $.ajax({
    type: 'POST',
    url: '{{ route('cookies.set') }}',
    data: {
      cookie_name: cookieName,
      cookie_val: cookieVal,
      _token: '{{ csrf_token() }}'
    },
    success: function(response) {
      console.log('Response:', response);
    }
  });
};

var loadEvents = function() {
  console.log('Load events');
  $.ajax({
    type: 'GET',
    url: '{{ route('cookies.events') }}',
    success: function(response) {
      console.log('Response:', response);
    }
  });
};

Template:

<button onclick="loadEvents();" type="button">Load Events</button>
<button onclick="setCookie('adminActiveCalendars', 'Foo');" type="button">Set Cookie Foo</button>
<button onclick="setCookie('adminActiveCalendars', 'Bar');" type="button">Set Cookie Bar</button>

Console output:

Load events
Object {cookieValue: null} // initially empty
Set cookie adminActiveCalendars Foo
Response: Object {previousCookieValue: null}
Load events
Response: Object {cookieValue: "Foo"} // first loadEvents request after setting cookie already holds correct value
Set cookie adminActiveCalendars Bar
Response: Object {previousCookieValue: "Foo"}
Load events
Response: Object {cookieValue: "Bar"}

After fully reloading the page, then loading events:

Load events
Response: Object {cookieValue: "Bar"} // still here, right from the start

Notes on alternative approaches:

  • Without knowing the internals of the application - it seems setting the cookie on the client side would be sufficient
  • Alternatively, store this kind of information in a Session variable rather than in a Cookie if it's not needed for something else on the client side. There are some differences . First of all you would not have to bother handling cookies on both sides (client and server).
  • Alternatively, do not store this information anywhere - add it to the request as filter parameters.

Original answer:

This doesn't set a cookie:

return view('welcome')->withCookie(cookie($cookieName, $cookieVal, 45000));

This does:

$response = new \Illuminate\Http\Response('Test');
$response->withCookie(cookie($cookieName, $cookieVal, 45000));
return $response;

Adaption of:

The problem is, if we want to reach our cookie, what we set on the front-end, we get null as a value. But is we use the $_COOKIE variable, we can access that, so that's the proof the cookie exists. What's the problem then?

By default, the framework brings a middleware for encrypting cookies. If we set a cookie from the back-end, it's automatically encrypted so Laravel can read that. From the JS we don't have any encryption, and that's why we can't access them from the framework.

In the app/Http/Kernel.php, in the web middleware group, we can find an EncryptCookies::class

IN array please set you cookie name which set using jquery or javascript

protected $except = [
'cookie-name',
];

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM