Drupal Nginx Json
Mon, 02/22/2016 - 10:33

Situation

I've got clientside jQuery which checks for new data every minute. Data is served by Drupal via json views_datasource module.

Problem

When ajax request has cache off it always creates request with timestamp e.g. _=1456134256000, and as it is get parameter, views are called and Drupal cache is not hit. And when cache is on, request is made without timestamp, and browser returns data from it's cache, so it doesn't hit server. What I needed is that script gets past browser cache, but hits Drupal cache.

Solution with nginx

What I've done is, that nginx removes _ argument from request and calls Drupal without it. That way I get avoid hitting browser cache, but Drupal returns cached data. I'm using views_content_cache, so the views cache is invalidated when new content is created, and served with next request.

Here are 2 changes I've done to nginx configuration.

  1. remove _ arg from #args
        location ~ ^/path/ {
                if ($args ~ (.*)&_=\d+(.*)) {
                        set $args $1$2;
                }
                rewrite ^/([^/]*)/(.*)(/?)$ /$1/index.php?q=$2;
        }
  1. remove _ arg from path called by fastcgi
        # save $request_uri
        set $request_url $request_uri;
        # modify request uri, remove '_' arg
        if ($request_uri ~ ^/path/(.*)&_=\d+(.*)) {
                set $request_url /path/$1$2;
        }

        location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                include fastcgi_params;
                # rewrite request uri by request url
                fastcgi_param REQUEST_URI $request_url;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_read_timeout 1800;
        }

Note: Better solution would probably be to use nodejs and socket.io to refresh data on client.