Async ignored on AJAX requests on Nginx server
- by eComEvo
Despite sending an async request to the server over AJAX, the server will not respond until the previous unrelated request has finished. The following code is only broken in this way on Nginx, but runs perfectly on Apache.
This call will start a background process and it waits for it to complete so it can display the final result.
$.ajax({
type: 'GET',
async: true,
url: $(this).data('route'),
data: $('input[name=data]').val(),
dataType: 'json',
success: function (data) { /* do stuff */}
error: function (data) { /* handle errors */}
});
The below is called after the above, which on Apache requires 100ms to execute and repeats itself, showing progress for data being written in the background:
checkStatusInterval = setInterval(function () {
$.ajax({
type: 'GET',
async: false,
cache: false,
url: '/process-status?process=' + currentElement.attr('id'),
dataType: 'json',
success: function (data) { /* update progress bar and status message */ }
});
}, 1000);
Unfortunately, when this script is run from nginx, the above progress request never even finishes a single request until the first AJAX request that sent the data is done. If I change the async to TRUE in the above, it executes one every interval, but none of them complete until that very first AJAX request finishes.
Here is the main nginx conf file:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 64;
# configure temporary paths
# nginx is started with param -p, setting nginx path to serverpack installdir
fastcgi_temp_path temp/fastcgi;
uwsgi_temp_path temp/uwsgi;
scgi_temp_path temp/scgi;
client_body_temp_path temp/client-body 1 2;
proxy_temp_path temp/proxy;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
# Sendfile copies data between one FD and other from within the kernel.
# More efficient than read() + write(), since the requires transferring data to and from the user space.
sendfile on;
# Tcp_nopush causes nginx to attempt to send its HTTP response head in one packet,
# instead of using partial frames. This is useful for prepending headers before calling sendfile,
# or for throughput optimization.
tcp_nopush on;
# don't buffer data-sends (disable Nagle algorithm). Good for sending frequent small bursts of data in real time.
tcp_nodelay on;
types_hash_max_size 2048;
# Timeout for keep-alive connections. Server will close connections after this time.
keepalive_timeout 90;
# Number of requests a client can make over the keep-alive connection. This is set high for testing.
keepalive_requests 100000;
# allow the server to close the connection after a client stops responding. Frees up socket-associated memory.
reset_timedout_connection on;
# send the client a "request timed out" if the body is not loaded by this time. Default 60.
client_header_timeout 20;
client_body_timeout 60;
# If the client stops reading data, free up the stale client connection after this much time. Default 60.
send_timeout 60;
# Size Limits
client_body_buffer_size 64k;
client_header_buffer_size 4k;
client_max_body_size 8M;
# FastCGI
fastcgi_connect_timeout 60;
fastcgi_send_timeout 120;
fastcgi_read_timeout 300; # default: 60 secs; when step debugging with XDEBUG, you need to increase this value
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
# Caches information about open FDs, freqently accessed files.
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# Turn on gzip output compression to save bandwidth.
# http://wiki.nginx.org/HttpGzipModule
gzip on;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_http_version 1.1;
gzip_vary on;
gzip_proxied any;
#gzip_proxied expired no-cache no-store private auth;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
# show all files and folders
autoindex on;
server {
# access from localhost only
listen 127.0.0.1:80;
server_name localhost;
root www;
# the following default "catch-all" configuration, allows access to the server from outside.
# please ensure your firewall allows access to tcp/port 80. check your "skype" config.
# listen 80;
# server_name _;
log_not_found off;
charset utf-8;
access_log logs/access.log main;
# handle files in the root path /www
location / {
index index.php index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root www;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9100
#
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9100;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# add expire headers
location ~* ^.+.(gif|ico|jpg|jpeg|png|flv|swf|pdf|mp3|mp4|xml|txt|js|css)$ {
expires 30d;
}
# deny access to .htaccess files (if Apache's document root concurs with nginx's one)
# deny access to git & svn repositories
location ~ /(\.ht|\.git|\.svn) {
deny all;
}
}
# include config files of "enabled" domains
include domains-enabled/*.conf;
}
Here is the enabled domain conf file:
access_log off;
access_log C:/server/www/test.dev/logs/access.log;
error_log C:/server/www/test.dev/logs/error.log;
# HTTP Server
server {
listen 127.0.0.1:80;
server_name test.dev;
root C:/server/www/test.dev/public;
index index.php;
rewrite_log on;
default_type application/octet-stream;
#include /etc/nginx/mime.types;
# Include common configurations.
include domains-common/location.conf;
}
# HTTPS server
server {
listen 443 ssl;
server_name test.dev;
root C:/server/www/test.dev/public;
index index.php;
rewrite_log on;
default_type application/octet-stream;
#include /etc/nginx/mime.types;
# Include common configurations.
include domains-common/location.conf;
include domains-common/ssl.conf;
}
Contents of ssl.conf:
# OpenSSL for HTTPS connections.
ssl on;
ssl_certificate C:/server/bin/openssl/certs/cert.pem;
ssl_certificate_key C:/server/bin/openssl/certs/cert.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Pass the PHP scripts to FastCGI server listening on 127.0.0.1:9100
location ~ \.php$ {
try_files $uri =404;
fastcgi_param HTTPS on;
fastcgi_pass 127.0.0.1:9100;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Contents of location.conf:
# Remove trailing slash to please Laravel routing system.
if (!-d $request_filename) {
rewrite ^/(.+)/$ /$1 permanent;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# We don't need .ht files with nginx.
location ~ /(\.ht|\.git|\.svn) {
deny all;
}
# Added cache headers for images.
location ~* \.(png|jpg|jpeg|gif)$ {
expires 30d;
log_not_found off;
}
# Only 3 hours on CSS/JS to allow me to roll out fixes during early weeks.
location ~* \.(js|css)$ {
expires 3h;
log_not_found off;
}
# Add expire headers.
location ~* ^.+.(gif|ico|jpg|jpeg|png|flv|swf|pdf|mp3|mp4|xml|txt)$ {
expires 30d;
}
# Pass the PHP scripts to FastCGI server listening on 127.0.0.1:9100
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9100;
}
Any ideas where this is going wrong?