Скрытые div для загрузки "ленивый JavaScript"? Возможные проблемы безопасности / другие? - PullRequest
2 голосов
/ 04 мая 2010

Мне любопытно мнение людей и мысли об этой ситуации. Причина, по которой я хотел бы лениво загрузить javascript, заключается в производительности. Загрузка javascript в конце тела уменьшает блокировку браузера и приводит к гораздо более быстрой загрузке страницы.

Но есть некоторая автоматизация, которую я использую для генерации html (в частности, django). Эта автоматизация имеет удобство, позволяя создавать формы с помощью «виджетов», которые выводят контент, необходимый для визуализации всего виджета (дополнительный javascript, css, ...). Проблема в том, что виджет хочет выводить 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> с некоторыми css (.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

Не обращая внимания на все детали моей конкретной реализации (конкретного носителя), я ищу консенсус в отношении того, может ли метод использования лениво загруженного JavaScript через скрытые скрытые теги создавать проблемы, связанные с безопасностью или другими?

Одна из наиболее удобных частей в этом заключается в том, что она следует принципу СУХОЙ ИМО, поскольку вам не нужно взламывать определенную ленивую загрузку для каждого экземпляра на странице. Это просто "работает".

ОБНОВЛЕНИЕ : Я не уверен, что у django есть возможность ставить вещи в очередь (посредством необычного наследования шаблонов или чего-то еще?) Для вывода непосредственно перед окончанием </body>?

Ответы [ 2 ]

1 голос
/ 04 мая 2010

Я бы предпочел инструмент, который позволяет мне «добавлять» контент в выходной поток ( или ) и добавлять его в буфер, который будет выводиться в конце страницы, непосредственно перед </body> tag.

Я не уверен, какие коммерческие инструменты поддерживают это (или поддерживает django?), но именно так я и построил свои фреймворки.

Что касается вашего вопроса о безопасности / другихвыдает ... скрипт будет обрабатываться всякий раз, когда его читают (если вы не выводите тег скрипта с атрибутом defer (в браузерах IE / более новых версиях)), таким образом, если он физически не перемещен, он не меняет поведение и не делает"lazy".

Мудро с точки зрения безопасности, извлекая контент из тега сценария и вызывая eval(), вы получаете возможность выполнения чего-то, что вы не планировали.(маловероятно, но возможно)

0 голосов
/ 04 мая 2010

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.

Тогда я бы не использовал этот виджет. Динамически предоставляемый клиентский скрипт со стороны клиента - это катастрофа, которая нарушит безопасность, если вы или ваш пользователь не будете мудрее. Как бы вы узнали, если этот код был скомпрометирован, например?

...