每次访问自己写的网页,看着哗啦啦的图片、css和js被重新请求,很烦,决定搞这个问题。为了优化访问网站的速度,看过一些资料,写了以下的代码。其主要思想是配置一下Etag。我也不懂网络协议,遇到问题就是到网络搜索,找现成的,或者问人找找方向。参考了几篇文献之后,写了下面的文字和代码,但我只在本地上试验成功,上传到GAE上似乎失败了,静态文件加载失败,应该需要改进。

参考文章:
1、《新增缓存机制 - HTTP Caching
2、《性能调优
3、《How to create a simple but powerful CDN with Google App Engine (GAE)

     我的软件环境是GAE+Django Helper,使用纯GAE的朋友可以参考上面提的第一篇文章和第三篇文章,或者网络搜索。下面是我自己摸索写出来的。如果已经发布网站了,修改了静态文件的话,建议修改一下静态文件的文件名。

一、GAE主要在app.ymal里配置一下。
- url: /media
static_dir: media
这样,静态文件就不用我们管了,但没有得到优化,每次req都得重新去取。

我们可以不借助GAE的力量,自己写url来处理静态文件,所以首先要在app.yaml里去掉上面举例的两行。

二、urls.py
    (’^media/(?P<fingerprint>[-=a-zA-Z0-9]+)/(?P<filename>[-=a-zA-Z0-9].*)’, ‘views.ForeverStaticFile’),

三、views.py
下面这个函数,可能写得不好,虽然达到了我想要的目的。参考代码如下:

def ForeverStaticFile(request,fingerprint,filename):
    logging.info(’—ForeverStaticFile—’)
  
    nowtime = datetime.utcnow()
    response = HttpResponse()
   
    cwd = os.getcwd()
    theme_path = os.path.join(cwd, ‘media’)
    filepath = theme_path + r’\’ + fingerprint + r’\’ + filename

    #max_age = 600 #expires in 10 minutes

    bHandle = False
    try:
        if_modified_since = request.META.get(‘HTTP_IF_MODIFIED_SINCE’, None)

        if if_modified_since:
            response.status_code = 304
            response.content = ‘’
            response[‘Content-Length’] = ‘0’
            return response
        bHandle = True
    except:
        bHandle = False

    if False == bHandle:
        ext = filename.split(’.’)[1]
        logging.info(ext)
        if types_map.has_key(ext):
            mime_type = types_map[ext]
        else:
            mime_type = ‘application/octet-stream’
        try:
            response["Content-Type"] = mime_type
            year = nowtime + timedelta(days=365)
            oldyear = nowtime - timedelta(days=365)
            response[‘Cache-Control’] = "public"
            response["Expires"] = format_date(year)
            response[‘Last-Modified’] = format_date(oldyear)
            response.write(open(filepath, ‘rb’).read())
            return response
        except Exception, e:
            logging.info(e)
          
    return response