Болезни Военный билет Призыв

Неоплачиваемый sign form action. PHP _SELF в атрибуте формы action

The HTTP (CSP) form -action directive restricts the URLs which can be used as the target of a form submissions from a given context.

CSP version Directive type default-src fallback
2
Navigation directive
No. Not setting this allows anything.
Syntax

One or more sources can be set for the form-action policy:

Content-Security-Policy: form-action ; Content-Security-Policy: form-action ;

Sources

can be one of the following:

Internet hosts by name or IP address, as well as an optional URL scheme and/or port number. The site"s address may include an optional leading wildcard (the asterisk character, "*"), and you may use a wildcard (again, "*") as the port number, indicating that all legal ports are valid for the source.
Examples:

  • http://*.example.com: Matches all attempts to load from any subdomain of example.com using the http: URL scheme.
  • mail.example.com:443: Matches all attempts to access port 443 on mail.example.com.
  • https://store.example.com: Matches all attempts to access store.example.com using https: .
A schema such as "http:" or "https:". The colon is required, single quotes shouldn"t be used . You can also specify data schemas (not recommended).
  • data: Allows data: URIs This is insecure; an attacker can also inject arbitrary data: URIs. Use this sparingly and definitely not for scripts.
  • mediastream: Allows mediastream: URIs to be used as a content source.
  • blob: Allows blob: URIs to be used as a content source.
  • filesystem: Allows filesystem: URIs to be used as a content source.
"self" Refers to the origin from which the protected document is being served, including the same URL scheme and port number. You must include the single quotes. Some browsers specifically exclude blob and filesystem from source directives. Sites needing to allow these content types can specify them using the Data attribute. "unsafe-inline" Allows the use of inline resources, such as inline elements, javascript: URLs, inline event handlers, and inline elements. You must include the single quotes. "unsafe-eval" Allows the use of eval() and similar methods for creating code from strings. You must include the single quotes. "none" Refers to the empty set; that is, no URLs match. The single quotes are required. "nonce-" A whitelist for specific inline scripts using a cryptographic nonce (number used once). The server must generate a unique nonce value each time it transmits a policy. It is critical to provide an unguessable nonce, as bypassing a resource’s policy is otherwise trivial. See unsafe inline script for an example. Specifying nonce makes a modern browser ignore "unsafe-inline" which could still be set for older browsers without nonce support. "-" A sha256, sha384 or sha512 hash of scripts or styles. The use of this source consists of two portions separated by a dash: the encryption algorithm used to create the hash and the base64-encoded hash of the script or style. When generating the hash, don"t include the or tags and note that capitalization and whitespace matter, including leading or trailing whitespace. See unsafe inline script for an example. In CSP 2.0 this applied only to inline scripts. CSP 3.0 allows it in the case of script-src for external scripts. "strict-dynamic" The strict-dynamic source expression specifies that the trust explicitly given to a script present in the markup, by accompanying it with a nonce or a hash, shall be propagated to all the scripts loaded by that root script. At the same time, any whitelist or source expressions such as "self" or "unsafe-inline" will be ignored. See script-src for an example. "report-sample" Requires a sample of the violating code to be included in the violation report. Examples Meta tag configuration Apache configuration Header set Content-Security-Policy "form-action "none"; Nginx configuration add_header Content-Security-Policy "form-action "none";" Violation case

Using a element with an action set to inline JavaScript will result in a CSP violation.

// Error: Refused to send form data because it violates the following // Content Security Policy directive: "form-action "none"".

Specifications Specification Status Comment
Content Security Policy Level 3
Working Draft No changes.
Content Security Policy Level 2
The definition of "form-action" in that specification.
Recommendation Initial definition.
Browser compatibility

The compatibility table in this page is generated from structured data. If you"d like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

Desktop Mobile Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Edge Mobile Firefox for Android Opera for Android Safari on iOS Samsung Internet form-action
Chrome Full support 40 Edge Full support 15 Firefox Full support 36 IE No support No Opera Full support 27 Safari Full support 10 WebView Android Full support Yes Chrome Android Full support Yes Edge Mobile No support No Firefox Android Full support 36 Opera Android ? Safari iOS Full support 9.3 Samsung Internet Android Full support Yes
Legend Full support Full support No support No support Compatibility unknown Compatibility unknown

Формы встречаются в интернете почти на каждом сайте. Например, когда Вы вводите логин и пароль на сайте, то данные заполняются через формы и отправляются на сервер. Также примером формы являются различные опросы.

Синтаксис тега

...

Тег имеет очень важный атрибут action , которому присваивается адрес (URL) скрипта, которому передается полученная информация с формы для обработки. Мы не будем углубляться в подробности того, что происходит после отправки данных, поскольку эти вопросы уже решает не html, а методы GET и POST в PHP.

Пример 1. Форма html с кнопками Это будут кнопки:
Кнопка один
Кнопка два
Кнопка три






После нажатия кнопки ОК, страница просто обновится, т.к. мы не прописали параметр action

Преобразуется на странице в следующее:

Это будут кнопки:
Кнопка один
Кнопка два
Кнопка три
А это будет текстовое поле. Например сюда можно вводить логин

А это будет большое текстовое поле. Например сюда можно ввести информацию о себе

После всего перечисленного будет кнопка ОК

После нажатия кнопки ОК, страница просто обновится, т.к. мы не прописали параметр action

Пояснения к примеру

  • action="" - говорит о том, что обработка данных будет происходить на этой же странице.
  • - атрибут type="radio" говорит о том, что нужно отобразить текст после этого кода, как кнопку выбора. Атрибут name и value в данном теге для нас сейчас играют маленькую роль, т.к. мы не изучаем сейчас php (см. уроки php).
  • - атрибут type="text" говорит о том, что это будет текстовое поле. Здесь так же есть два важных атрибута: name (для php) и value (значение по умолчанию).
  • - атрибут type="textarea" говорит о том, что это будет большое текстовое поле. Разница от предыдущего случая лишь в том, что он позволяет записывать большой объем текста.
  • - атрибут type="submit" говорит о том, что это кнопка. В атрибуте value пишется то, что будет написано на кнопке.

Более подробно про все эти элементы можно прочитать в 15 уроке: элементы тега , где рассмотрены радиокнопки, списки, флажки, текстовые поля, кнопки.

Теперь рассмотрим подробно все атрибуты тега .

Атрибуты и свойства тега

1. Атрибут accept-charset="Кодировка" - определяет кодировку, в которой сервер может принимать и обрабатывать данные формы. Может принимать различные значения, например, CP1251, UTF-8 и т.п.

2. Атрибут action="URL" - адрес скрипта, который обрабатывает передаваемые данные от формы. Если оставить это значение пустым, то данные будут обрабатываться в этом же документе, где расположена форма.

3. Атрибут autocomplete="on/off" - задает или отключает автозаполнение формы. Может принимать два значения:

  • on - включить автозаполнение;
  • off - выключить автозаполнение;

4. Атрибут enctype="параметр" - задает способ кодирования данных. Может принимать следующие значения:

  • application/x-www-form-urlencoded - вместо пробелов ставится +, символы вроде русских букв кодируются их шестнадцатеричными значениями
  • multipart/form-data - данные не кодируются
  • text/plain - пробелы заменяются знаком +, буквы и другие символы не кодируются.

5. Атрибут method="POST/GET" - задает метод отправки. Может принимать два значения:

  • GET - передача данных в адресной строке (есть ограничение по объёму отправки данных)
  • POST - посылает на сервер данные в запросе браузера (может отправить большое количество данных, т.к. нету ограничения объёма)

6. Атрибут name="имя" - задает имя формы. Чаще всего используется в случае наличия множества форм для того, чтобы можно было обратиться к конкретной форме через скрипт.

7. Атрибут novalidate - отменяет встроенную проверку данных формы на корректность ввода.

8. Атрибут target="параметр" - имя окна или фрейма, куда обработчик будет загружать возвращаемый результат. Может принимать следующие значения:

  • _blank - загружает страницу в новое окно браузера
  • _self - загружает страницу в текущее окно
  • _parent - загружает страницу во фрейм-родитель
  • _top - отменяет все фреймы и загружает страницу в полном окне браузера

Уважаемый читатель, теперь Вы узнали гораздо больше о html теге form. Теперь советую перейти к следующему уроку.

  • Перевод
  • Tutorial

Это третья статья в серии, где я описываю свой опыт написания веб-приложения на Python с использованием микрофреймворка Flask.

Цель данного руководства - разработать довольно функциональное приложение-микроблог, которое я за полным отсутствием оригинальности решил назвать microblog.

Краткое повторение В предыдущей части мы определили простой шаблон для домашней страницы и использовали мнимые объекты в качестве прототипов вещей, которых у нас еще нет. К примеру пользователи или записи.

В этой статье мы собираемся заполнить один из пробелов, которые есть в нашем приложении. Мы рассмотрим работу с формами.

Формы являются одними из самых основных блоков в любом веб-приложении. Использование форм позволит пользователям оставлять записи в блоге, а также логиниться в приложение.

Чтобы следовать этой части, ваше приложение микроблога должно быть таким, каким мы оставили его в конце предыдущей. Пожалуйста, убедитесь, что прилолжение установлено и работает.

Конфигурация Для обработки форм мы будем использовать расширение Flask-WTF , которое является оберткой WTForms и прекрасно интегрируется с Flask приложениями.

Многие расширения Flask требуют некоторой настройки, поэтому мы создадим файл конфигурации внутри нашей корневой папки microblog, так что он будет легко доступен для изменения, если понадобится. Вот с чего мы начнем (файл config.py):
CSRF_ENABLED = True SECRET_KEY = "you-will-never-guess"

Все просто, это две настройки, которые нужны нашему расширению Flask-WTF . CSRF_ENABLED активирует предотвращение поддельных межсайтовых запросов. В большинстве случаев вы захотите включить эту опцию, что сделает ваше приложение более защищенным.

SECRET_KEY нужен только тогда, когда включен CSRF . Он используется для создания криптографического токена, который используется при валидации формы. Когда вы пишете свое приложение, убедитесь, что ваш секретный ключ сложно подобрать.

Теперь у нас есть конфиг, и мы должны сказать Flask"у прочесть и использовать его. Мы сможем сделать это сразу после того, как объект приложения Flask создан. (файл app/__init__.py):
from flask import Flask app = Flask(__name__) app.config.from_object("config") from app import views

Форма входа В Flask-WTF формы представлены в виде объектов подкласса от класса Form . Подкласс форм просто определяет поля форм как переменные в классе.

Мы создадим форму логина, которая будет использоваться вместе с системой идентификации. Механизм входа, который мы будем поддерживать в нашем приложении, не стандартного типа имя пользователя/пароль, - мы будем использовать OpenID в качестве логинов. Преимущество OpenID в том, что авторизация пройдена у провайдера OpenID, поэтому нам не нужно проверять пароли, что сделает наш сайт более защищенным для наших пользователей.

OpenID логин требует только одну строку под названием OpenID. Также мы закинем чекбокс "Запомнить меня" в форму, чтобы пользователь мог установить cookie в свой браузер, который будет помнить их логин, когда они вернутся.

Напишем нашу первую форму (файл app/forms.py):
from flask.ext.wtf import Form from wtforms import TextField, BooleanField from wtforms.validators import Required class LoginForm(Form): openid = TextField("openid", validators = ) remember_me = BooleanField("remember_me", default = False)

Уверен, что класс говорит сам за себя. Мы импортировали класс Form и два класса полей, который нам понадобятся, TextField и BooleanField .

Импортированный Required - это валидатор, функция, которая может быть прикреплена к полю, для выполнения валидации данных отправленных пользователем. Валидатор Required просто проверяет, что поле не было отправлено пустым. В Flask-WTF есть много валидаторов, мы будем использовать несколько новых в будущем.

Шаблоны форм Еще нам нужен HTML шаблон, который содержит форму. Хорошей новостью будет то, что класс LoginForm , который мы только что создали, знает как отдавать поля формы в HTML, поэтому нам просто нужно сконцентрироваться на макете. Вот наш шаблон логина: (файл app/templates/login.html):
Sign In {{form.hidden_tag()}}

Please enter your OpenID:
{{form.openid(size=80)}}

{% endblock %}

Обратите внимание, что мы снова используем шаблон base.html через оператор наследования, расширяя его. Мы будем делать так со всеми нашими шаблонами, обеспечивая согласование макета на всех страницах.

Есть несколько интересных отличий между обычной HTML формой и нашим шаблоном. Шаблон ожидает экземпляр класса формы, который мы только что назначили в аргументе шаблона form . Мы позаботимся об отправке этого аргумента шаблона в будущем, когда напишем функцию представления, которая отдает этот шаблон.

Параметр шаблона form.hidden_tag() будет заменен скрытым полем для предотвращения CSRF, включенное в нашем файле настроек. Это поле должно быть во всех ваших формах, если CSRF включен.

Поля нашей формы отданы объектом формы, вы просто должны обращаться к аргументу {{form.field_name}} в том месте шаблона, где должно быть вставлено поле. Некоторые поля могут принимать аргументы. В нашем случае, мы просим форму создать наше поле openid с шириной в 80 символов.

Так как мы не определили кнопку отправки в классе формы, мы должны определить её как обычное поле. Поле отправки не несет каких-либо данных, поэтому нет нужды определять его в классе формы.

Представления форм Последним шагом перед тем, как мы сможем увидеть нашу форму, будет написание функции представления, которая отдает шаблон.

На самом деле это весьма просто, так как мы должны всего лишь передать объект формы в шаблон. вот наша новая функция представления (файл app/views.py):
from flask import render_template, flash, redirect from app import app from forms import LoginForm # функция представления index опущена для краткости @app.route("/login", methods = ["GET", "POST"]) def login(): form = LoginForm() return render_template("login.html", title = "Sign In", form = form)

Мы импортировали наш класс LoginForm , создали его экземпляр и отправили в шаблон. Это все что нужно для того, чтобы отрисовать поля формы.

Не будем обращать внимания на импорт flash и redirect . Мы используем их чуть позже.

Еще одно нововведение - это аргументы метода в декораторе route . Здесь мы говорим Flask, что функция представления принимает GET и POST запрос. Без этого представление будет принимать только GET запросы. Мы хотим получать POST запросы, которые будут отдавать форму с веденными пользователем данными.

На этой стадии вы можете запустить приложение и посмотреть на вашу форму в браузере. После запуска откройте адрес, который мы связали с функцией представления login: http://localhost:5000/login

Мы еще не запрограммировали ту часть, которая принимает данные, поэтому нажатие на кнопку submit не принесет никакого эффекта.

Получение данных формы
Еще одна область, где Flask-WTF облегчает нашу работу - обработка отправленных данных. Это новая версия нашей функции представления login , которая валидирует и сохраняет данные формы (файл app/views.py):
@app.route("/login", methods = ["GET", "POST"]) def login(): form = LoginForm() if form.validate_on_submit(): flash("Login requested for OpenID="" + form.openid.data + "", remember_me=" + str(form.remember_me.data)) return redirect("/index") return render_template("login.html", title = "Sign In", form = form)

Метод validate_on_submit делает весь процесс обработки. Если вы вызвали метод, когда форма будет представлена пользователю (т.е. перед тем, как у пользователя будет возможность ввести туда данные), то он вернет False , в таком случае вы знаете, что должны отрисовать шаблон.

Если validate_on_submit вызывается вместе как часть запроса отправки формы, то он соберет все данные, запустит любые валидаторы, прикрепленные к полям, и если все в порядке вернет True , что указывает на валидность данных. Это означает, что данные безопасны для включения в приложение.

Если как минимум одно поле не проходит валидацию, тогда функция вернет False и это снова вызовет отрисовку формы перед пользователем, тем самым дав возможность исправить ошибки. Позже мы научимся показывать сообщения об ошибке, когда не проходит валидация.

Когда validate_on_submit возвращает True , наша функция представления вызывает две новых функции, импортированных из Flask. Функция Flash - это быстрый способ отображения сообщения на следующей странице, представленной пользователю. В данном случае мы будем использовать это для отладки до тех пор, пока у нас нет инфраструктуры, необходимой для логирования, вместо этого мы просто будем выводить сообщение, которое будет показывать отправленные данные. Также flash чрезвычайно полезен на продакшн сервере для обеспечения обратной связи с пользователем.

Flash сообщения не будут автоматически появляться на нашей странице, наши шаблоны должны отображать сообщени в том виде, который подходит для макета нашего сайта. Мы добавим сообщения в базовый шаблон, так что все наши шаблоны наследуют эту функциональность. Это обновленный шаблон base (файл app/templates/base.html):
{% if title %} {{title}} - microblog {% else %} microblog {% endif %} Microblog: Home {% with messages = get_flashed_messages() %} {% if messages %}

    {% for message in messages %}
  • {{ message }}
  • {% endfor %}
{% endif %} {% endwith %} {% block content %}{% endblock %}

Надеюсь способ отображения сообщений не требует пояснений.

Другая новая функция, которую мы использовали в нашем представлении login - redirect . Эта функция перенаправляет клиентский веб-браузер на другую страницу, вместо запрашиваемой. В нашей функции представления мы использовали редирект на главную страницу, разработанную в предыдущих частях. Имейте в виду, что flash сообщения будут отображены даже если функция заканчивается перенаправлением.

Прекрасное время для того, чтобы запустить приложение и проверить как работают формы. Попробуйте отправить форму с пустым полем openid, чтобы увидеть как валидатор Required останавливает процесс передачи.

Улучшение валидации полей С приложением в его текущем состоянии, переданные с неверными данными формы не будут приняты. Вместо этого форма снова будет отдана пользователю для исправления. Это именно то, что нам нужно.

Что мы пропустили, так это уведомления пользователя о том, что именно не так с формой. К счастью, Flask-WTF также облегчает эту задачу.

Когда поле не проходит валидацию Flask-WTF добавляет наглядное сообщение об ошибке в объект формы. Эти сообщения доступны в шаблоне, так что нам просто нужно добавить немного логики для их отображения.

Это наш шаблон login с сообщениями валидации полей (файл app/templates/login.html):
{% extends "base.html" %} {% block content %} Sign In {{form.hidden_tag()}}

Please enter your OpenID:
{{form.openid(size=80)}}
{% for error in form.errors.openid %} [{{error}}] {% endfor %}

{{form.remember_me}} Remember Me

{% endblock %}

Единственное изменение, которое мы сделали - добавили цикл, отрисовывающий любые добавленные валидатором сообщения об ошибках справа от поля openid. Как правило, любые поля имеющие прикрепленные валидаторы будут иметь ошибки, добавленные как form.errors.имя_поля. В нашем случае мы используем form.errors.openid . Мы отображаем эти сообщения в красном цвете, чтобы обратить на них внимание пользователя.

Взаимодействие с OpenID На деле, мы будем сталкиваться с тем, что много людей даже не знают, что у них уже есть парочка OpenID. Не слишком известно, что ряд крупных поставщиков услуг в интернете поддерживает OpenID аутентификацию для их пользователей. Например, если у вас есть аккаунт в Google, то с ним у вас есть и OpenID. Так же как и в Yahoo, AOL, Flickr и множестве других сервисов.

Чтобы облегчить пользователю вход на наш сайт с одним из часто используемых OpenID, мы добавим ссылки на часть из них, чтобы пользователю не нужно было вводить OpenID вручную.

Начнем с определения списка OpenID провайдеров, которых мы хотим представить. Мы можем сделать это в нашем файле конфигурации (файл config.py):
OPENID_PROVIDERS = [ { "name": "Google", "url": "https://www.google.com/accounts/o8/id" }, { "name": "Yahoo", "url": "https://me.yahoo.com" }, { "name": "AOL", "url": "http://openid.aol.com/" }, { "name": "Flickr", "url": "http://www.flickr.com/" }, { "name": "MyOpenID", "url": "https://www.myopenid.com" }]

Теперь посмотрим как мы используем этот список в нашей функции представления login:
@app.route("/login", methods = ["GET", "POST"]) def login(): form = LoginForm() if form.validate_on_submit(): flash("Login requested for OpenID="" + form.openid.data + "", remember_me=" + str(form.remember_me.data)) return redirect("/index") return render_template("login.html", title = "Sign In", form = form, providers = app.config["OPENID_PROVIDERS"])

Тут мы получаем настройки путем их поиска по ключу в app.config . Дальше список добавляется в вызов render_template как аргумент шаблона.

Как вы догадались, нам нужно сделать еще один шаг, чтобы покончить с этим. Сейчас нам нужно указат как мы хотели бы отображать ссылки на этих провайдеров в нашем шаблоне login (файл app/templates/login.html):
{% extends "base.html" %} {% block content %} function set_openid(openid, pr) { u = openid.search("") if (u != -1) { // openid requires username user = prompt("Enter your " + pr + " username:") openid = openid.substr(0, u) + user } form = document.forms["login"]; form.elements["openid"].value = openid } Sign In {{form.hidden_tag()}}

Please enter your OpenID, or select one of the providers below:
{{form.openid(size=80)}} {% for error in form.errors.openid %} [{{error}}] {% endfor %}
|{% for pr in providers %} {{pr.name}} | {% endfor %}

{{form.remember_me}} Remember Me

{% endblock %}

Шаблон получился несколько длинным в связи со всеми этими изменениями. Некоторые OpenID включают в себя имена пользователей, для них у нас должно быть немного javascript магии, которая запрашивает имя пользователя, а затем создает OpenID. Когда пользователь кликает на ссылку OpenID провайдера и (опционально) вводит имя пользователя, OpenID для этого провайдера вставляется в текстовое поле.

скриншот нашей страницы входа после нажатия на ссылку Google OpenID

Заключительные слова Хотя мы добились большого прогресса с нашими формами логина, в действительности мы не сделали ничего для входа пользователей в нашу систему. Все что мы сделали имело отношение к GUI процесса входа. Это потому, что прежде чем мы сможем сделать реальные логины, нам нужно иметь базу данных, где мы можем записывать наших пользователей.

В следующей части мы мы поднимем и запустим нашу базу данных, чуть позже мы завершим нашу систему входа, так что следите за обновлениями следующих статей.

Приложение microblog в его текущем состоянии доступно для загрузки здесь.

В этой статье подробно говорится об использовании переменной PHP _SELF.

Что за переменная PHP _SELF?

Переменная PHP _SELF возвращает имя и путь к текущему файлу (относительно корня документа). Вы можете использовать эту переменную в атрибуте формы action. Существуют также некоторые нюансы, которые вы должны знать. Мы, конечно, никак не можем обойти стороной эти нюансы.

Давайте рассмотрим несколько примеров.

Echo $_SERVER["PHP_SELF"];

1) Предположим, что ваш php файл расположен по следующему адресу:

Http://www.yourserver.com/form-action.php

В этом случае переменная PHP _SELF будет содержать:

"/form-action.php"

2) Предположим, ваш php файл расположен по такому адресу:

Http://www.yourserver.com/dir1/form-action.php

PHP _SELF будет:

"/dir1/form-action.php"

PHP _SELF в атрибуте формы action. Для чего она там понадобилась?

Обычно переменную PHP _SELF используют в атрибуте action тега form . В атрибуте action указывается адрес, по которому будет отослано содержание формы после подтверждения (клик пользователем по кнопке с type="submit"). Как правило это таже самая страница, с которой ушла форма.

Однако, если вы переименуете файл, на который ссылается форма, вам понадобится переименовать название файла в атрибуте action , иначе форма работать не будет.

Переменная PHP _SELF избавит вас от лишних исправлений, так как адрес страницы будет генерироваться автоматически, исходя из названия файла.

Допустим, у вас есть файл с формой form-action.php, и вы хотите, чтобы после подтверждения форма отправлялась на тот же самый файл. Обычно пишут так:

Но вы можете использовать переменную PHP _SELF вместо form-action.php. В этом случае код будет выглядеть: