PHP不能使用 header 进行 301 跳转

看到一个段PHP代码做跳转的时候是输出的 javascript 而没有使用 header(‘Location: xxx’) ,于是将其改为了 header(‘Location: xxx’)。

结果不能正常跳转,显示空白,监控 http 请求发现,即使在我设置完 header 完之后直接 exit 的情况下,服务器端仍然输出了 3bit 的字符。

于是开始找是哪输出的这 3bit ,从入口的 index.php 直到设置 header 的地方都没有任何输出。。。

最后只能用 exit 从 index.php 入口处一句一句代码的中断调试,追踪到引入 config 文件的时候发现这 3bit 的输出是从 config 文件中输出的。

打开 config 通读代码却没有发现任何输出语句,百思不得其解。。。

后来突然想到会不会是字符编码的问题,因为PHP会将文件的 bom 信息输出,PHP在有内容输出后又不能设置 header ,因此导致 header 函数无效?

查看该文件编码 utf8格式 ,印象中3年前搭建项目的时候应该全站源码都是 utf8无bom 格式。于是修改文件编码格式,问题解决。

这种莫名其妙的Bug其实只要开发的同学细心点就能避免的。

1年前一个同学遇到这个问题的时候问过我,因为我已离职,没有全面的检查代码就没有能解决。

没想到今年回来后,这个问题还是由我来解决了。。。

nginx 下载文件不完整

使用 nginx 搭建静态文件服务器,下载稍大的文件时出现只能下载来来文件的一部分的问题。

用 wget 可以下载完整的文件。

后来使用 strace wget http://xxx/xxx.xx 打印详细的下载log 发现:文件在传输的过程中跟nginx的连接中断了几次,wget有自动重连的机制,最后才下载下来了完整的文件,而浏览器在连接中断后则认为文件已经传输完成,以至于出现只能下载文件的一部分的情况。

后来分析可能是中间用 nginx 做了一次代理的缘故,尝试配置host直接从静态文件服务器的nginx中下载,没有出现连接中断的情况。

最后将代理 nginx 的配置文件中添加 ( proxy_buffering off; #关闭代理的缓冲功能) 配置,问题解决。

参考文献:http://blog.csdn.net/ikmb/article/details/7098080

java URLConnection 实现文件上传

* 此工具类不建议上传大文件(百兆以上),大文件有内存溢出的风险。如果需要传大文件,可使用 hc 另行实现。
* 此工具类适用于普通网站中用户上传的图片、小附件等文件存储。

	public static HashMap upload(MultipartFile file, String domain, boolean isProtected){
		HashMap map = null;
		
		URI uri = URI.create("http://static.myechinese.com/up");
		InetSocketAddress sa = new InetSocketAddress("218.106.246.55", 80);
		Proxy proxy = new Proxy(Type.HTTP, sa);
		try {
			URLConnection conn = uri.toURL().openConnection(proxy);
			String boundary = "---------------------------" + System.currentTimeMillis();
			String boundaryInContent = "--" + boundary;
			String rn = "\r\n";
			conn.addRequestProperty("Connection", "keep-alive");
			conn.addRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setConnectTimeout(1000);
			conn.setUseCaches(false);
			conn.connect();
			OutputStream out = conn.getOutputStream();
			StringBuilder sb = new StringBuilder();
			sb.append(boundaryInContent).append(rn);
			sb.append("Content-Disposition: form-data; name=domain").append(rn).append(rn);
			sb.append(domain).append(rn);
			sb.append(boundaryInContent).append(rn);
			sb.append("Content-Disposition: form-data; name=isProtected").append(rn).append(rn);
			sb.append(isProtected).append(rn);
			sb.append(boundaryInContent).append(rn);
			sb.append("Content-Disposition: form-data; name=file; filename=" + file.getOriginalFilename()).append(rn);
			sb.append("Content-Type: " + file.getContentType()).append(rn).append(rn);
			out.write(sb.toString().getBytes());
			out.write(file.getBytes());
			sb.delete(0, sb.length());
			sb.append(rn).append(boundaryInContent).append("--").append(rn).append(rn);
			out.write(sb.toString().getBytes());
			out.flush();
			out.close();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String res = reader.readLine();
			reader.close();
			System.out.println("Uploader: " + res);
			map = new Gson().fromJson(res, HashMap.class);// Gson 有点坑,数字默认给转成 Double 类型
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return map;
	}

nginx + lua 搭建静态文件服务器 lua utf8 转 gb2312

./configure –prefix=/srv/nginx-1.6.0 –with-file-aio –with-http_image_filter_module –with-http_flv_module –with-http_mp4_module –with-http_gzip_static_module –with-http_stub_status_module –add-module=../ngx_devel_kit-0.2.19 –add-module=../lua-nginx-module-0.9.7 && make && make install


#user  nobody;
worker_processes  4;

error_log  /var/log/nginx/error.log  info;

pid        logs/nginx.pid;

worker_rlimit_nofile 50000;

events {
    use  epoll;
    worker_connections  50000;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    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  /var/log/nginx/access.log  main;

    sendfile           on;
    sendfile_max_chunk 256K;
    tcp_nopush         on;

    log_not_found  off;

    open_file_cache          max=1024 inactive=60s;
    open_file_cache_valid    60s;
    open_file_cache_min_uses 2;
    open_file_cache_errors   on;

    keepalive_timeout  0;

    gzip  on;

    server_tokens off;

    client_max_body_size 256m;
    client_body_temp_path /dev/shm/client_body_temp 1 2;
    fastcgi_temp_path /dev/shm/fastcgi_temp 1 2;
    proxy_temp_path /dev/shm/proxy_temp 1 2;

    lua_package_path '/usr/local/share/luajit-2.0.3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/socket/?.lua;;';
    lua_package_cpath '/usr/local/lib/lua/5.1/?.so;;';
    init_by_lua 'iconv, cjson, redis = require "iconv", require "cjson", require "redis"';
    
    server {
        listen       80;
        server_name  static.******.com;
        root         /var/static.******.com;
        set $script_path '/var/static.******.com/scripts';
        location / {
            return 403;
        }
        location = /crossdomain.xml {
            #Flash request require this file.
        }
        location = /up {
            access_by_lua 'ngx.req.set_uri("/scripts/upload_script.php")';
            include fastcgi.conf;
        }
        location = /accessToken {
            access_by_lua 'ngx.req.set_uri("/scripts/accessToken_script.php")';
            include fastcgi.conf;
        }
        location ~ ^/([^\/]+)/([\w]+)/info$ {
            default_type "application/json";
            set $domain $1;
            set $fn $2;
            access_by_lua_file $script_path/info.lua;
        }
        location ~ ^/([^\/]+)/([\w]+)$ {
            set $domain $1;
            set $fn $2;
            access_by_lua_file $script_path/stream_and_download.lua;
        }
        location ~ ^/([^\/]+)/([\w]+)/([\d]+)/([\d]+)$ {
            set $domain $1;
            set $fn $2;
            set $width $3;
            set $height $4;
            access_by_lua_file $script_path/image_filter.lua;
            image_filter resize $width $height;
        }
        location ~ "^/([^\/]+)/([\w]{2})([\w]{2})([\w]{2})([\w]{26})\.flv$" {
            try_files /$1/$2/$3/$4/$2$3$4$5.flv =404;
            flv;
        }
        location ~ "^/([^\/]+)/([\w]{2})([\w]{2})([\w]{2})([\w]{26})\.mp4$" {
            try_files /$1/$2/$3/$4/$2$3$4$5.mp4 =404;
            mp4;
            mp4_buffer_size       1m;
            mp4_max_buffer_size   5m;
        }
    }
}