代码之家  ›  专栏  ›  技术社区  ›  dlamotte

隐藏的div用于“lazy javascript”加载?可能的安全/其他问题?

  •  2
  • dlamotte  · 技术社区  · 14 年前

    我很好奇人们对这种情况的看法和想法。我之所以喜欢延迟加载javascript是因为性能。在正文末尾加载javascript可以减少浏览器阻塞,并最终得到更快的页面加载。

    将以下小部件添加到窗体时,可以看到它呈现一些 <script>...</script> 标签:

    class AutoCompleteTagInput(forms.TextInput):
        class Media:                                                    
            css = {
                'all': ('css/jquery.autocomplete.css', )
            }                                             
            js = (
                'js/jquery.bgiframe.js',
                'js/jquery.ajaxQueue.js',                               
                'js/jquery.autocomplete.js',
            )       
    
        def render(self, name, value, attrs=None):        
            output = super(AutoCompleteTagInput, self).render(name, value, attrs)
            page_tags = Tag.objects.usage_for_model(DataSet)
            tag_list = simplejson.dumps([tag.name for tag in page_tags],
                                        ensure_ascii=False)
            return mark_safe(u'''<script type="text/javascript">                  
                jQuery("#id_%s").autocomplete(%s, {
                    width: 150,                                         
                    max: 10,
                    highlight: false,
                    scroll: true,
                    scrollHeight: 100,
                    matchContains: true,
                    autoFill: true              
            });                               
            </script>''' % (name, tag_list,)) + output
    

    我的建议是如果有人使用 <div class=".lazy-js">...</div> .lazy-js { display: none; } )还有一些javascript( jQuery('.lazy-js').each(function(index) { eval(jQuery(this).text()); } ),您可以有效地强制所有javascript在页面加载结束时加载:

    class AutoCompleteTagInput(forms.TextInput):
        class Media:                                                    
            css = {
                'all': ('css/jquery.autocomplete.css', )
            }                                             
            js = (
                'js/jquery.bgiframe.js',
                'js/jquery.ajaxQueue.js',                               
                'js/jquery.autocomplete.js',
            )       
    
        def render(self, name, value, attrs=None):        
            output = super(AutoCompleteTagInput, self).render(name, value, attrs)
            page_tags = Tag.objects.usage_for_model(DataSet)
            tag_list = simplejson.dumps([tag.name for tag in page_tags],
                                        ensure_ascii=False)
            return mark_safe(u'''<div class="lazy-js">                  
                jQuery("#id_%s").autocomplete(%s, {
                    width: 150,                                         
                    max: 10,
                    highlight: false,
                    scroll: true,
                    scrollHeight: 100,
                    matchContains: true,
                    autoFill: true              
            });                               
            </div>''' % (name, tag_list,)) + output
    

    关于这一点,最方便的部分之一是它很好地遵循了DRY原则,因为您不需要为页面中的每个实例设置特定的延迟负载。它只是“工作”。

    :我不确定django是否有能力(通过花哨的模板继承或其他方式)在测试结束前将输出排队 </body>

    2 回复  |  直到 14 年前
        1
  •  1
  •   scunliffe    14 年前

    我更喜欢一个工具,让我“附加”的内容到输出流( </body>

    至于你关于安全/其他问题的问题。。。无论何时读取脚本,脚本都将进行处理(除非输出带有 defer 属性(在IE/较新的浏览器中)因此,除非它被物理移动,否则它不会改变行为或使其“懒惰”。

    eval() 它打开了你的可能性的东西执行,你没有计划(不太可能,但可能)

        2
  •  0
  •   austin cheney austin cheney    14 年前

    The problem is that the widget wants to output javascript immediately into the middle of the document, but I want to ensure all javascript loads at the end of the body.

    那我就不用那个小部件了。从客户端动态提供的客户端脚本是一场灾难,它将破坏安全性,而您或您的用户却没有变得更聪明。例如,你怎么知道代码是否被泄露了?