Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: form auth и basic auth, вызов jenkins json api из сервлета?

Добрый день,

JSP, Tomcat, Java

Друзья подскажите и/ли помогите, дайте правильные вектор - как сделать web app который мог бы вызывать jenkins json api используя один логин?

Проблема в авторизации, я сделал авторизацию form (j_username,j_password) в апп.

Потом апп, по запросу пользователя, может вызвать jenkins json api, например чтобы собрать список текущих joboв (те же самые credentials, но auth method basic), как заимплементить так чтобы один раз залогиневшись в апп, пользователю, вызывая каждый раз jenkins json api, не нужно было бы вводить те же самые credentials опять и опять.

На данный момент ajax вызывает jsp, который формирует запрос к jenkins json api и делает новый HttpURLConnection и обрабатывает результат. Возможно я что то перемудрил здесь, но всеравно не понимаю как быть с авторизацией.


заранее спасибо!
Ответ: vipi voxa,

Вам в ветку java.
Та выбрать метод.
Даже простейшая базовая авторизация не будет спрашивать пароль пока сессия не кончится.
После базовой идет форм. Там формочка покрасивше и такая как нарисуете.

Модератор: Тема перенесена из форума "HTML, JavaScript, VBScript, CSS".
Вопрос: Авторизация, requests, form

Добрый день.

Очень нужна помощь - собираюсь попарсить сайт и не могу пройти авторизацию.
История такая - есть отдельный сайт с авторизацией:

В нем только логин, пароль и кнопка.

Если все хорошо, то возвращается и начинает загружаться новый url(каждый раз разный), который мы и хотим парсить.

Мысли по алгоритму были следующие:
1. Сначала делаем GET, получаем Cookie с какими то параметрами, которые как нам кажется нам нужны.
2. Делаем POST, с параметрами из п.1, логином, паролем и еще какими то постоянными параметрами. По замыслу на выходе мы должны получить новый URL. и по нему в рамках session уже делать что хотим
3. В рамках одной session парсить новый URL.

Остановился я на пункте 2. Новый URL не получается никак вообще(смотрю на результаты и ничего похожего на url не вижу).
Подскажите пожалуйста, что же я делаю не так?
Поиском пользовался, собственно и код ниже - результат пользования им и документацией...


Код Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import requests
import lxml.html
#from requests.auth import HTTPBasicAuth
from lxml import html
 
 
 
globurl = 'https://bet.asianodds88.com/Login.aspx'
headers = {
   'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
   'Accept': 'text/html, application/xhtml+xml, */*',
   'Accept-Language': 'ru-RU',
   'Connection' : 'Keep-Alive',
   'DNT': '1',
   'Host' : 'bet.asianodds88.com'
}
   
session = requests.session()
 
data = session.get(globurl, headers=headers)
 
cook = requests.utils.dict_from_cookiejar(session.cookies)
 
page = lxml.html.fromstring(data.content)
 
form = page.forms[0]
 
form.fields['__VIEWSTATE'] = '/wEPDwUKLTI1ODEwMTU2NWRkqnybRQ09QVoJRk+/t14HK+xCTMFKKH/U4g5xI5jKbEg='
form.fields['__EVENTVALIDATION'] = '/wEdAAYKEE/V9mKS5VSYR7crf/qfrYQ7cNL5e4Px1H7qjIiiGBkyjkS0it80+RpYtX5f+bH1O3oqhV33p03rM6Mgqg6UQ9M+R09aX7xg3Y20MK3GJ2ojXMsv1cA6odwI/XEYGecC0ZbECwZO3HfgS+sj64c6Mqb7LWjIJNzxbz/VxNN1Hg=='
form.fields['hiddClientTimezoneOffset'] = '-180'
form.fields['hiddMd5Pass'] = '389ef5d7965aea167940688bbda1ed42'
form.fields['txtUserID'] = логин
form.fields['txtPass'] = 'пароль'
form.fields['btnDoLogin'] ='Login'
 
            
headers1 = {
   'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2516.0 Safari/537.36',
   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
   'Accept-Language': 'ru-RU',
   'Connection' : 'Keep-Alive',
   'Content-Length' : '445',
   'Content-Type' : 'application/x-www-form-urlencoded',
   'Host' : 'bet.asianodds88.com',
   'Origin' : 'https://bet.asianodds88.com',
   'Referer' : 'https//bet.asianodds88.com/Login.aspx',
   'Upgrade-Insecure-Requests' : '1'
}
 
response = session.post(globurl, data=form.form_values(), headers = headers1, cookies = cook)
 
print(response.text)
print(response.cookies)
Ответ: Prevateer, Ну, а что же ты хочешь. Приходится запускать браузер и им рулить, это же отдельное огромное приложение.

Ну если там только при авторизации js код, надо интерпретировать, а дальше можно обойтись просто запросами, то можно авторизоваться и получить куки с помощью selenium, а дальше работать с помощью requests. Так будет быстрее все)
Вопрос: Создание форм авторизации и заставки (Splash-формы) в приложениях

Создание формы для авторизации в приложении.

Очень многие делают это совершенно неправильно: уже после того, как написано приложение добавляют еще одну форму, и хотят сделать так, чтобы сначала открывалась новая форма, а потом, когда пользователь введет пароль для входа в программу, скрыть ее и уже продолжать создавать формы как и раньше, до добавления формы авторизации. Это в корне неправильный подход. По нескольким причинам:
  1. Если при таком решении форма авторизации будет назначена главной формой приложения, ее потом нельзя будет закрыть, можно будет только скрыть, иначе при закрытии главной формы будет автоматически закрыто само приложение
  2. Главная (и все остальные) форма приложения вообще не должны создаваться до тех пор, пока пользователь не подтвердит своих прав на использование данного продукта. Иначе очень просто будет чуть более продвинутому пользователю показать уже созданную, но скрытую форму, чем если бы ее вообще еще не существовало

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

Решение очень простое: создаем форму авторизации, убираем ее из списка автоматически создаваемых (Project -> Options -> Forms, перенести форму из списка Auto-create в список Available)

На форме расположим 2 поля ввода (edUser для ввода логина и edPass для ввода пароля) и 2 кнопки (btnLogIn для подтверждения и btnCancel для отмены авторизации)

По нажатию на кнопку LogIn на форме авторизации либо просто проверяем соответствие пары логин/пароль:
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm3::Button1Click(TObject *Sender)
{
    if (edUser->Text == "volvo" && edPass->Text == "test")
    {
        ModalResult = mrOk; // в случае соответствия возвращаем один результат
    }
    else
    {
        ModalResult = mrCancel; // иначе - другой. Этот же результат - и по нажатию на кнопку Cancel
    }
}
, либо делаем чуть более интересно: пару логин/хеш пароля храним в Ini-файле, и при нажатии на LogIn проверяем соответствие:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void __fastcall TForm3::Button1Click(TObject *Sender)
{
    std::auto_ptr<TIniFile> ini (new TIniFile(ChangeFileExt(ParamStr(0), ".ini"))); // #include <IniFiles.hpp>
    std::auto_ptr<TIdHashMessageDigest5> hash(new TIdHashMessageDigest5); // #include <IdHashMessageDigest.hpp>
 
    if(ini->ReadString("users", edUser->Text, "") == hash->HashStringAsHex(edPass->Text, TIdTextEncoding::Default))
    {
        ModalResult = mrOk;
    }
    else
    {
        ModalResult = mrCancel;
    }
}
Разумеется, можно придумать еще много способов хранения паролей или их хешей, но основная идея этого поста - дать общее понимание того, что же делать с этой формой дальше, как ее показать, чтобы только после успешной аутентификации выполнение программы шло дальше.

Для этого в класс формы авторизации нужно добавить статический метод Execute:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class TForm3 : public TForm
{
__published:    // IDE-managed Components
    // ...
private:    // User declarations
public:     // User declarations
    __fastcall TForm3(TComponent* Owner);
    static bool __fastcall Execute(); // <--- Вот его описание
};
 
// а вот - реализация:
bool __fastcall TForm3::Execute()
{
    TForm3 *frm = new TForm3(0);
    int res = frm->ShowModal();
    delete frm;
    return res == mrOk; // вернуть признак успешной авторизации
}
А теперь открываем главный файл проекта (Project -> View source), и меняем порядок создания форм с того, что было раньше:
C++
1
2
3
4
5
6
         Application->Initialize();
         Application->MainFormOnTaskBar = true;
 
         Application->CreateForm(__classid(TForm1), &Form1);
         Application->CreateForm(__classid(TForm2), &Form2);
         Application->Run();
на такой:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        if(TForm3::Execute()) // сначала показываем форму авторизации
        {
            // и только если результат авторизации успешен - создаем главную форму приложения
            Application->Initialize();
            Application->MainFormOnTaskBar = true;
            Application->CreateForm(__classid(TForm1), &Form1);
            Application->Run();
        }
        else
        {
            // иначе показываем сообщение о невозможности войти в программу,
            // и приложение завершается, не создавая никаких форм
            Application->MessageBox(
                _T("Вы не можете пользоваться приложением, так как не прошли авторизацию"),
                _T("Защита приложения")
            );
        }
Это самый простой метод авторизации, когда пользователь просто вводи свой логин/пароль, и в случае, если он ввел их правильно, он получает возможность использовать приложение. Чуть более интересно будет добиться того, чтобы в приложении было несколько групп пользователей, скажем, админ и просто пользователь. Тут тоже есть несколько вариантов реализации:
  1. Сделать одну форму, на которой в зависимости от некоего глобального флажка динамически создавать набор компонентов, нужный для представителя группы пользователей, к которой принадлежит залогинившийся (способ очень хорош тем, что на форме оказываются только необходимые данной группе пользователей компоненты, но для сложных форм с большим количеством компонентов на них создавать все динамически может быть долго по времени)
  2. Все так же сделать одну форму, но уже в дизайнере набросать на нее две группы компонентов (например, на разные вкладки TPageControl, или на разные TPanel), и по значению того же глобального флажка показывать одну вкладку (панель), и скрывать все остальные (этот способ гораздо проще, но теперь на форме, хоть и скрытыми, одновременно присутствуют все компоненты для всех групп пользователей, и все обработчики событий)
  3. Сделать разные формы для разных групп пользователей и создавать/показывать только нужную, остальные вообще не создавать.

Вариант №3 - самый оптимальный. Для его реализации нужно чуть-чуть изменить описание класса формы авторизации:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
enum AuthStatus {authNone, authUser, authAdmin}; // это список всех возможных групп пользователей
 
class TForm3 : public TForm
{
__published:    // IDE-managed Components
    TLabeledEdit *edUser;
    TLabeledEdit *edPass;
    TButton *btnLogin;
    TButton *btnCancel;
    void __fastcall btnCancelClick(TObject *Sender);
    void __fastcall btnLoginClick(TObject *Sender);
private:    // User declarations
public:     // User declarations
    __fastcall TForm3(TComponent* Owner);
    static AuthStatus __fastcall Execute();
    static AuthStatus status; // Добавляем флажок
 
};
AuthStatus TForm3::status = authNone; // инициализация статического поля класса
и реализацию обработчика клика по кнопке и метода Execute() :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void __fastcall TForm3::btnLoginClick(TObject *Sender)
{
    // разумеется, тут точно так же можно сделать проверку паролей
    // из INI-файла, только тогда в файле придется еще хранить
    // роль каждого пользователя в системе
    if (edUser->Text == "volvo" && edPass->Text == "test")
    {
        status = authAdmin;
        ModalResult = mrOk;
    }
    else
    if (edUser->Text == "nata" && edPass->Text == "second")
    {
        status = authUser;
        ModalResult = mrOk;
    }
    else
    {
        ModalResult = mrCancel;
    }
}
 
// ---------------------------------------------------------------------------
AuthStatus __fastcall TForm3::Execute()
{
    TForm3 *frm = new TForm3(0);
    TForm3::status = authNone;
    frm->ShowModal();
    delete frm;
    return TForm3::status; // Возвращаем статус пользователя
}
, и изменить главный файл приложения:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
        AuthStatus st = TForm3::Execute(); // получаем статус пользователя
        if (st != authNone) // если авторизация была успешной
        {
            Application->Initialize();
            Application->MainFormOnTaskBar = true;
            switch (st)
            {
            case authAdmin: // залогинился админ - создаем админскую форму
                Application->CreateForm(__classid(TForm1), &Form1);
                // тут можно создать еще формы, которые нужны только админу
                break;
            case authUser: // простой пользователь - создаем пользовательскую
                Application->CreateForm(__classid(TForm2), &Form2);
                // те формы, которые нужны только для пользовательского аккаунта - можно создать здесь
                break;
            }
 
            // при необходимости - создаем другие общие формы здесь
            Application->Run();
        }
        else // авторизация не пройдена
        {
            Application->MessageBox(
                _T("Вы не можете пользоваться приложением, так как не прошли авторизацию"),
                _T("Защита приложения")
            );
        }
Таким образом можно не только отслеживать успешность/неуспешность авторизации, но и создавать свои формы для любого количества групп пользователей.

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

В качестве примера реализаций привожу два проекта: первый - иллюстрирует чтение логина/пароля из INI, а второй - создание разных форм для каждой из групп пользователей (проекты были созданы и протестированы в Builder XE2, для создания INI-файла использовался код:
C++
1
2
3
4
5
6
7
8
9
#include <memory>
#include <IdHashMessageDigest.hpp>
 
// ...
 
    std::auto_ptr<TIniFile> ini (new TIniFile(ChangeFileExt(ParamStr(0), ".ini")));
    std::auto_ptr<TIdHashMessageDigest5> hash(new TIdHashMessageDigest5);
    ini->WriteString("users", "volvo", hash->HashStringAsHex("test", TIdTextEncoding::Default));
    ini->WriteString("users", "nata", hash->HashStringAsHex("second", TIdTextEncoding::Default));
)

Проект №1

Проект №2

P.S. Замечания/пожелания/вопросы по этой теме отсылайте мне в ЛС, я постараюсь добавить еще интересные методы авторизации.
Ответ:
Создание заставок (splash-форм) для приложения.


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


Как же создаются подобные заставки? Все очень просто, и чем-то похоже на создание формы авторизации (наверное, тем, что опять нужно лезть в файл проекта, и менять так порядок создания форм). Итак:

  1. Когда все остальные формы приложения уже созданы и работают, создаем новую форму, которая будет заставкой.
  2. Сразу же идем в свойства приложения, и убираем новую форму из списка автоматически создаваемых (Project->Options->Forms переносим форму из списка Auto-Create в список Available)
  3. Поскольку мы хотим, чтобы форма какое-то время показывалась на экране, то кладем на нее таймер, задаем максимальное время показа заставки, и по таймеру проверяем, не вышло ли еще это время:

    C++
    1
    2
    3
    4
    5
    6
    7
    8
    
    void __fastcall TSplashForm::Timer1Timer(TObject *Sender)
    {
        static int SplashTime = 3000;
        if((::GetTickCount() - FStart > SplashTime) && CanCloseSplash)
        {
            this->Close();
        }
    }
    (о назначении CanCloseSplash я расскажу чуть позже)
  4. Естественно, если не записать в FStart значение GetTickCount() при создании заставки, ничего работать не будет. Поэтому пишем обработчик создания формы:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    void __fastcall TSplashForm::FormCreate(TObject *Sender)
    {
        FStart = ::GetTickCount();
        CanCloseSplash = false; // начальная инициализация всех полей
        Timer1->Interval = 100;
        
        // если кого-то раздражает показ заставки на самом верху,
        // следующую строку можно закомментировать
        FormStyle = fsStayOnTop; 
    }
    Ну вот практически и все, что нужно сделать с формой. Осталось только правильно ее показать.
  5. Идем в главный файл проекта (Project -> View source), и добавляем там показ формы-заставки:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
             SplashForm = new TSplashForm(0); // создаем
             SplashForm->Show(); // и показываем заставку
     
             // теперь продолжаем инициализацию и создание главной формы приложения
             Application->Initialize();
             Application->MainFormOnTaskBar = true;
             Application->CreateForm(__classid(TMainForm), &MainForm);
             
             // сразу после того, как главная форма была создана,
             // можно закрывать заставку (если до этого время не вышло
             // и она не закрылась самостоятельно)
     
             if(SplashForm)
             {
                SplashForm->CanCloseSplash = true; // даем разрешение закрыть заставку
             }
             // и запускаем метод Run, что приведет к показу главной формы
             Application->Run();

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

Можно сделать чуть по-другому: сразу после того, как создалась главная форма, закрывать заставку. Как ни странно, для этого понадобится изменить всего лишь 2 символа в обработчике таймера:
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TSplashForm::Timer1Timer(TObject *Sender)
{
    static int SplashTime = 3000;
    // Меняем "И" на "ИЛИ", и теперь либо закончится время
    // показа заставки, либо CanCloseSplash станет true; заставка
    // закроется при выполнении любого из этих условий
    if((::GetTickCount() - FStart > SplashTime) || CanCloseSplash)
    {
        this->Close();
    }
}
Тестовые проекты
BCB6:


XE2:



Это все, конечно, прекрасно, но хочется же красивостей. Давайте попробуем создать заставку в виде изображения с прозрачностью.

Изменений в главном файле проекта почти не будет, единственное, что я поменял - это вместо метода Show вызвал самописный метод ShowSplash:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
         SplashForm = new TSplashForm(0);
         SplashForm->ShowSplash("logo.png"); // <---
 
         Application->Initialize();
         Application->MainFormOnTaskBar = true;
         Application->CreateForm(__classid(TMainForm), &MainForm);
 
         if(SplashForm)
         {
            SplashForm->CanCloseSplash = true;
         }
 
         Application->Run();
А вот реализация класса формы-заставки поменялась значительно. Во-первых, в класс формы добавился прототип того самого метода ShowSplash():
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class TSplashForm : public TForm
{
__published:    // IDE-managed Components
    TTimer *Timer1;
    void __fastcall Timer1Timer(TObject *Sender);
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    void __fastcall FormDestroy(TObject *Sender);
private:    // User declarations
    int FStart;
    bool FCanCloseSplash;
 
public:     // User declarations
    __fastcall TSplashForm(TComponent* Owner);
    void __fastcall ShowSplash(String fn); // <---
 
    __property bool CanCloseSplash = {read = FCanCloseSplash, write = FCanCloseSplash};
};
Ну, и реализация (в XE+ использовался модуль Vcl.Imaging.pngimage.hpp)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
void __fastcall Create_Premult_Bitmap(Graphics::TBitmap *bm)
{
    for (int y = 0; y < bm->Height; y++)
    {
        Vcl::Imaging::Pngimage::TByteArray *dst =
            (Vcl::Imaging::Pngimage::TByteArray*)bm->ScanLine[y];
        for (int x = 0; x < bm->Width; x++)
        {
            dst->data[x * 4] = dst->data[x * 4] * dst->data[x * 4 + 3] >> 8;
            dst->data[x * 4 + 1] =
                dst->data[x * 4 + 1] * dst->data[x * 4 + 3] >> 8;
            dst->data[x * 4 + 2] =
                dst->data[x * 4 + 2] * dst->data[x * 4 + 3] >> 8;
        };
    };
}
 
void __fastcall Load_Logo(Graphics::TBitmap *bm, String FileName)
{
    std::auto_ptr<TPngImage> png (new TPngImage);
    png->LoadFromFile(FileName);
    bm->PixelFormat = pf32bit;
    bm->Width = png->Width;
    bm->Height = png->Height;
    for (int y = 0; y < png->Height; y++)
    {
        Vcl::Imaging::Pngimage::TByteArray *alpha = png->AlphaScanline[y];
        TRGBLine *src = (TRGBLine*)png->Scanline[y];
        Vcl::Imaging::Pngimage::TByteArray *dst =
            (Vcl::Imaging::Pngimage::TByteArray*)bm->ScanLine[y];
        for (int x = 0; x < png->Width; x++)
        {
            dst->data[x * 4] = src->data[x].rgbtBlue;
            dst->data[x * 4 + 1] = src->data[x].rgbtGreen;
            dst->data[x * 4 + 2] = src->data[x].rgbtRed;
            dst->data[x * 4 + 3] = alpha->data[x];
        }
    }
}
 
void __fastcall TSplashForm::ShowSplash(String fn)
{
    BorderStyle = bsNone;
    Position = poDesktopCenter;
    this->FormStyle = fsStayOnTop;
 
    SIZE s1;
 
    BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
 
    TPoint p = Classes::Point(0, 0);
    ::SetWindowLong(Handle, GWL_EXSTYLE, ::GetWindowLong(Handle,
        GWL_EXSTYLE) | WS_EX_LAYERED);
 
    std::auto_ptr<Graphics::TBitmap> image (new Graphics::TBitmap);
    Load_Logo(image.get(), ExpandFileName(ExtractFilePath(ParamStr(0))) + fn);
    Create_Premult_Bitmap(image.get());
    s1.cx = image->Width;
    s1.cy = image->Height;
 
    Width = image->Width;
    Height = image->Height;
 
    std::auto_ptr<Graphics::TBitmap> layer (new Graphics::TBitmap);
    layer->PixelFormat = pf32bit;
    layer->Width = s1.cx;
    layer->Height = s1.cy;
    layer->Canvas->Brush->Color = RGB(0, 0, 0);
    layer->Canvas->FillRect(layer->Canvas->ClipRect);
 
    ::AlphaBlend(layer->Canvas->Handle, 0, 0, image->Width, image->Height,
        image->Canvas->Handle, 0, 0, image->Width, image->Height, blend);
    Create_Premult_Bitmap(layer.get());
    ::UpdateLayeredWindow(this->Handle, 0, NULL, &s1, layer->Canvas->Handle, &p,
        0, &blend, ULW_ALPHA);
 
    Show();
}
Тестовые проекты
BCB6:
собрать не получилось. Я уже говорил, что использую Portable версию Билдера, туда нельзя добавлять новые компоненты, нельзя даже просто откомпилировать pas-файл, поэтому работать с PNG не представляется возможным

XE2:




А теперь о грустном. У первого метода есть недостаток (на самом деле он есть и у второго, но поскольку картинка обычно статичная - он не так бросается в глаза). Заключается он в следующем: если при инициализации основной формы (как раз в то время, когда показывается заставка) не вызывать периодически Application->ProcessMessages(), как я делал в тестовом приложении, то форма не будет обновляться. Она просто повиснет в том состоянии, в котором была создана, и на нее не положишь ни ProgressBar, ни Label, в которые можно вывести какую-то информацию о том, на каком этапе находится сейчас процесс загрузки приложения.

Чтобы этого избежать можно:
  1. Вынести все действия по инициализации в отдельный поток.
  2. Создать и показать заставку
  3. Запустить поток инициализации
  4. По завершению работы потока закрывать заставку

Убиваем двух зайцев: во-первых, ОС не считает заставку "зависшей" формой, во-вторых, пользователь тоже так не считает, поскольку видит, что информация на ней меняется. Приведу, кому интересно, пример приложения, реализующего вышеописанную схему, с потоком. Запустите и посмотрите (для того, чтобы проверить - добавил искусственных задержек в поток)

Тестовые проекты
BCB6:


XE2:




Ну вот и все, пожалуй, о Splash-формах.


P.S. Замечания/пожелания/вопросы приветствуются, обращайтесь в ЛС, если будет что-то интересное - добавлю в пост.
Вопрос: Авторизация multipart/form-data; boundary

Здравствуйте, нужно написать авторизацию для одного сайта, но есть проблема, не знаю как работать с таким типом, вот так выглядит пост запрос(лишний текст убрал)
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryJULxXIapzAsqKqmx
Referer: ***
Accept-Encoding: ***
Accept-Language: ***
Cookie: ***
Content-Length: ***

------WebKitFormBoundaryJULxXIapzAsqKqmx
Content-Disposition: form-data; name="_pd"

#sCmnToken#**********************#eCmnToken#
------WebKitFormBoundaryJULxXIapzAsqKqmx--

Как это все организовать на synapse?
Нужен код, и что такое boundary? Всегда имеет разное значение, в общем вопрос в том как отправить этот пост запрос
Ответ:
Delphi
1
2
3
4
5
6
7
8
9
THTTPSend.MimeType := 'multipart/form-data; boundary=----WebKitFormBoundaryJULxXIapzAsqKqmx';
 
S := '------WebKitFormBoundaryJULxXIapzAsqKqmx' + #13#10;
S := S + 'Content-Disposition: form-data; name="_pd"' + #13#10;
S := S + #13#10;
S := S + '#sCmnToken#**********************#eCmnToken#' + #13#10;
S := S + '------WebKitFormBoundaryJULxXIapzAsqKqmx--';
 
WriteStrToStream(THTTPSend.Document, S);
Все будет работать.
И да, можно преобразовать в обычный вид "a=b&b=c" и слать с обычный типом "application/x-www-form-urlencoded'" и все будет работать.
Вопрос: Laravel 5 Не видит класс Form

Пытаюсь создать простенькую форму на странице...но постоянно появляются одна и та же ошибка "Class 'Form' not found"

В композер.json добавил строку
Код JSON
1
2
3
4
5
6
7
....
    "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.1.*",
        "illuminate/html": "5.*"
    },
....
потом обновил композер командой
php composer.phar update

Добавил несколько строчек в файл настроек app.php в папке config


Код PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  
// это providers
...      
Illuminate\View\ViewServiceProvider::class,
Illuminate\Html\HtmlServiceProvider::class,
...
 
// это aliases
..
        'View'      => Illuminate\Support\Facades\View::class,
        'Form'      => Illuminate\Html\FormFacade::class,
        'Html'      => Illuminate\Html\HtmlFacade::class,
    ],
...
Сама структура проекта такая:
в роуторе есть строка
Код PHP
1
Route::any('auth', 'PageController@index');
с помощью artisan создал контроллер PageController, а в его методе index прописал код вызова вида(представления):
Код PHP
1
2
3
4
    public function index()
    {
        return \View::make('auth',array('title'=>'регистрация'));
    }
а в модели прописал код
Код PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 <!DOCTYPE html>
 <html lang="en">
 <head>
    <meta charset="UTF-8">
    <title><?=$title;?></title>
 </head>
 <body>
 <?php
 
    echo "файл auth.blade.blade";
?>
 
<h2>Регистрация</h2><br>
 
<?php echo Form::open(array('method' =>'post', 'class'=>'formstyle'));?>
 
<p>
<?php echo Form::text('login',null, array('id'=>'login','placeholder'=>'ваш логин', 'required'));?> 
</p>
<p>
<?php echo Form::email('email',null, array('id'=>'email','placeholder'=>'ваш email', 'required'));?>    
</p>
<p>
<?php echo Form::password('password', array('id'=>'pass','placeholder'=>'ваш пароль', 'required'));?>   
</p>
<p>
<?php echo \orm::password('password_confirmation', array('placeholder'=>'повторите пароль', 'required'));?> 
</p>
<p>
<?php echo Form::button('Зарегистрироваться', array('class'=>'btn btn-default'));?> 
</p>
<?php echo Form::close();?>
 
 </body>
 </html>
Пробовал и другой код для вида, но результат тот же, само представление лежит в той же папке что и стандартное welcome.blade.php.Согласно терминалу линукса само обновление композера произошло вроде без ошибок, были установленные соответствующие компоненты. Возможно классы с формой стоит перенести в какой-то каталог. В чем может быть ошибка?
Ответ: Наверно уже поздно, но я дружил еще с 4 Latavel, советую попробовать заменить это:
Код HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php echo Form::open(array('method' =>'post', 'class'=>'formstyle'));?>
 
<p>
<?php echo Form::text('login',null, array('id'=>'login','placeholder'=>'ваш логин', 'required'));?> 
</p>
<p>
<?php echo Form::email('email',null, array('id'=>'email','placeholder'=>'ваш email', 'required'));?>    
</p>
<p>
<?php echo Form::password('password', array('id'=>'pass','placeholder'=>'ваш пароль', 'required'));?>   
</p>
<p>
<?php echo \orm::password('password_confirmation', array('placeholder'=>'повторите пароль', 'required'));?> 
</p>
<p>
<?php echo Form::button('Зарегистрироваться', array('class'=>'btn btn-default'));?> 
</p>
<?php echo Form::close();?>
На вот это:

Код HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{{ Form::open(array('method' =>'post', 'class'=>'formstyle')) }}
 
<p>
{{ Form::text('login',null, array('id'=>'login','placeholder'=>'ваш логин', 'required')) }}
</p>
<p>
{{ Form::email('email',null, array('id'=>'email','placeholder'=>'ваш email', 'required')) }}
</p>
<p>
{{ Form::password('password', array('id'=>'pass','placeholder'=>'ваш пароль', 'required'));?>   
</p>
<p>
{{ Form::password('password_confirmation', array('placeholder'=>'повторите пароль', 'required')) }}
</p>
<p>
{{ Form::button('Зарегистрироваться', array('class'=>'btn btn-default')) }}
</p>
{{ Form::close() }}
Вот решение вам:
Вопрос: Ошибка при добавлении form

привет всем

при добавлении form дает ошибку -- "элемент form должен быть вложен в элемент form"

вот код

HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
    <form id="form1" runat="server">
    <div>
     <div class="wrap">
        <div class="header_top">
            <div class="logo">
                <a href="index.html"><img src="http://www.cyberforum.ru/images/logo.png" alt="" /></a>
            </div>
              <div class="header_top_right">
                <div class="search_box">
 
                    [U]<form> -- вот тут и выдает ошибку -- "элемент form должен быть вложен в элемент form"[/U]
 
                        <input type="text" value="Search for Products" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Search for Products';}"><input type="submit" value="SEARCH">
                    </form>
                </div>
в чем тут ошибка, помогите пожалуйста
Ответ: Тэги <form> нельзя вкладывать друг в друга.
Вопрос: сессия и form select

доброго времени суток! подскажите как сделать, чтобы $name имела значение select, и как добавить сессию, чтобы select сохранял выбор в форме.

<form method="post">
<
select name="select" onchange="this.form.submit()">
<
option value="1">1</option>
<
option value="2">2</option>
</
select>
</
form>

<?
if (isset($_POST['select'])) $name= $_POST['select'];
echo $name;
?>


Это сообщение отредактировал zhenia3003 - 30.07.2014 - 08:17
Ответ: Или вообще вот так

<?php

if(isset($_POST['select'])) {
setcookie("select",(int)$_POST['select'], time()+3600); //Записать куку
}

$select = array(
1=>'',
2=>''
);

$cityname = array(
1=>'blagoveschensk',
2=>'raychihinsk'
);

$option = isset($_POST['select']) ? (int)$_POST['select'] : (isset($_COOKIE["select"]) ? (int)$_COOKIE["select"] : 1);
$select[$option] = 'selected';
$cityname = $cityname[$option];

?>

<form method="post" style="display:inline-block; width:140px; height:30px; top:5px; left:10px; position:absolute; z-index:14;">
<
select class="citychange" name="select" onchange="this.form.submit()">
<
option value="1" <?=$select[1]?>>Благовещенск</option>
<
option value="2" <?=$select[2]?>>Райчихинск</option>
</
select>
</
form>
Вопрос: Вызов php функции через form get

привет.
учусь php, есть два файла:
index.php
Код PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?
    include 'calc.php';
?>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
    <title>Калькулятор</title>
</head>
<body>
    <form method=get action="calc.php">
        <input type="text" name="first">
        <input type="text" name="second">
        <select size="1" name="action">
            <option value="sum">Сложить</option>
            <option value="min">Вычесть</option>
            <option value="mult">Умножить</option>
            <option value="dev">Разделить</option>
            <option value="stepen">Возвести в степень</option>
            <option value="procent">Процент от числа</option>
            <option value="koren">Корень</option>
        </select>
        <input type="submit" value="Равно">
    </form>
    <?= calc($action, $first, $second); ?>
</body>
</html>
calc.php
Код PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?
function calc($action, $first, $second)
{
    //global $action, $result, $first, $second;
    echo $action;
    echo $result;
    echo $first;
    echo $second;
    switch($action)
    {
        case "sum": $result = $first+$second; break;
        case "min": $result = $first-$second; break;
        case "mult": $result = $first*$second; break;
        case "dev": 
        if (!$second) //если второе число равно "0" или вообще не введено
        {
            exit("Извините, программа не может выполнить действие: на ноль делить нельзя");
        }
        $result=$first/$second; break;
        case "procent": $result = $first*($second/100); break;
        case "stepen": $result = pow($first, $second); break;
        case "koren": $result = pow($first,0.5); break;
    } //заканчиваем оператор switch
    return $result;
}
?>
первый после заполнения формы должен вызвать функцию calc(), та же в свою очередь должна все высчитать и вернуть значение... но вместо этого она просто открывается в этой же вкладке.
чего тут не хватает?
Ответ:
Цитата Сообщение от Leningradeс Посмотреть сообщение
а как все же сделать что бы я мог вызвать функцию и получить её результат в первом файле? а то выходит результат оказывается во втором файле.
Код PHPHTML
1
2
3
4
5
6
7
<form>
    <input type='text' name='result'>
    <input type='submit'>
</form>
<?php
if (isset($_GET['result']))
    echo "Результат: ".$_GET['result'];
Вопрос: Вывод выбранного form select

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

А вопрос такой: Как вывести выбранный элемент из выпадающего списка ?

Имеется такой самопальный html-php код
Код PHP
1
2
3
4
5
6
7
8
9
10
11
12
<?php 
  $values=array("FFF","AAAA","CCC"); // массив с значениями
        
        $number=count($values);   //функция для дознавания числа элементов массива что выше
    ?>
        <form method="post">    //сама форма 
        <select name="polling">      //выпадающее меню, которое забивается массивом  
    <?    for($i=0; $i<$number; $i++) echo "<option value=\"$i\"> $values[$i]</option>"; ?>  //забивание выпадающего списка
        </select> 
        <input type="submit" value="Ok" />
        </form>  <br/>
      <?php  echo ??  ?> //Выбранный элемент из списка
Ответ: Всем привет!
А если несколько SELECT-ов, как сделать так что бы одним SUBMIT-ом передать в несколько переменных значения?
Например:
Код PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
<?php 
$values=array("FFF","AAAA","CCC");
$number=count($values);
?>
<form method="post">
<select name="polling">     
<?php  
for($i=0; $i<$number; $i++) echo "<option value=\"$i\"> $values[$i]</option>"; 
?>
</select>
<select name="polling1">     
<?php  
for($i=0; $i<$number1; $i++) echo "<option value=\"$i\"> $values1[$i]</option>"; 
?>
</select>
<input type="submit" value="Ok" />
</form>
 
<?php 
if(isset($_POST['polling'])) echo $_POST['polling']; 
?>
Вопрос: В чём заключается разница между VSL Form и VSL Forms Application?

В чём заключается разница между VSL Form и VSL Forms Application? Заранее спасибо за ответ)
Ответ: KseniyaGS, во первых не VSL а VCL ( - библиотека визуальных компонентов).
VCL Form - форма для приложения. Не является программой. Невозможно запустить.
VCL Forms Application - Оконное приложение. Можно запустить как программу. Использует форму_ы (VCL Form)