Можете ли вы выбрать целевой браузер на стороне сервера? - PullRequest
1 голос
/ 31 марта 2011

У меня есть форма, которая позволяет пользователям выбирать чеки, а при отправке создает PDF-файл, который открывается на новой вкладке браузера.Он не имеет какого-либо бренда и, вероятно, в любом случае откроется в плагине, поэтому я не хочу, чтобы он занимал вкладку моего сайта.Поэтому я установил target формы _blank.

Но пользователь может отправить форму без достаточной информации для создания PDF, в этом случае я отмечаю ошибку (на стороне сервера) иперерисовать формуНо поскольку я установил цель формы, этот повторный рендеринг также открывается на новой вкладке, и это не , что я хочу - в этом случае я хочу, чтобы он вел себя так, как если бы target были _top.

Итак, вопрос таков: Могу ли я изменить целевую серверную часть рендеринга браузера?

Да, я знаю, что это можно сделать с помощью клиентского JavaScript, но меня раздражает JS, и я все равно должен выполнить проверку на стороне сервера.Я могу в конечном итоге использовать его, но, пожалуйста, не предлагайте это как ответ - мне более любопытно, может ли то, что я пытаюсь сделать, сделать.

PS: Я работаю на Ruby on Rails 2.3.8, на случай, если кто-нибудь знает решение для фреймворка.

Ответы [ 2 ]

1 голос
/ 31 марта 2011

Обойти эту проблему можно было бы с помощью заголовка размещения содержимого в PDF, чтобы принудительно загрузить файл и избежать целевого «целевого» подхода.

Content-type: application/pdf

Content-Disposition: attachment; filename="downloaded.pdf"
0 голосов
/ 31 марта 2011

Нет. Это чисто клиентская функция. На самом деле, вполне возможно получить браузер, который поддерживает только одно окно и где атрибут target не будет иметь никакого эффекта. Были даже попытки полностью исключить этот атрибут из будущих стандартов HTML (например, у ветви XHTML такого атрибута не было).

Единственное совпадение, которое я могу вспомнить между HTML и HTTP, - это теги <meta http-equiv> (где HTML может повлиять на поведение, контролируемое HTTP). HTTP - это протокол передачи, разработанный для работы практически с любыми данными. Позволить ему контролировать представление было бы довольно ужасной смесью проблем.

К счастью, мы живем в мире JavaScript. Проверить форму довольно просто, используя запрос AJAX, особенно с такими библиотеками, как jQuery.

Например, этот скрипт выполняет запрос POST к URL-адресу (в данном случае /pdf/validate) и ожидает, что страница отправит обратно «хорошо» (если все хорошо) или что-то еще, если произошла ошибка.

<form method="post" action="/pdf/send" id="pdf-form">
    <!-- form stuff here -->
</form>

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
    // set to true if we are to bypass the check
    // this will happen once we've confirmed the parameters are okay
    var programmaticSubmit = false;

    // attach an event handler for when the form is submitted
    // this allows us to perform our own checks beforehand; we'll do so by
    // cancelling the event the user triggered, and do the submit ourselves if
    // we detect no error
    $('#pdf-form').submit(function(event)
    {
        if (!programmaticSubmit)
        {
            // first off, cancel the event
            event.preventDefault();

            // do an AJAX request to /pdf/validate
            $.ajax("/pdf/validate", {
                type: "POST",
                data: $(this).serialize(),  // send the form data as POST data
                success: function(result)
                {
                    // this gets called if the HTTP request did not end
                    // abnormally (i.e. no 4xx or 5xx status);
                    // you may also want to specify an "error" function to
                    // handle such cases
                    if (result == "ok")
                    {
                        // since the server says the data is okay, we trigger
                        // the event again by ourselves, but bypassing the
                        // checks this time
                        programmaticSubmit = true;
                        $(this).submit();
                    }
                    else // something went wrong! somehow display the error
                        alert(result);
                }
            });
        }
    });
});
</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...