webkit form 提交

如何请求一个url, form数据如何发送过去?

gtk版本的webkit是用soup库来请求资源, 在webCore/platform/network/soup/ResouceHandlerSoup.cpp:static bool startHTTPRequest(ResourceHandle* handle)中对资源请求。ResourceHandle中有这样一个函数ResourceRequest& firstRequest(),返回ResourceRequest类,它是维护http请求信息的并且继承ResourceRequestBase类。ResourceRequestBase类有这些数据:

        KURL m_url;

        ResourceRequestCachePolicy m_cachePolicy;

        double m_timeoutInterval; // 0 is a magic value for platform default on platforms that have one.

        KURL m_firstPartyForCookies;

        String m_httpMethod;

        HTTPHeaderMap m_httpHeaderFields;

        Vector<String> m_responseContentDispositionEncodingFallbackArray;

        RefPtr<FormData> m_httpBody;

        bool m_allowCookies;

        mutable bool m_resourceRequestUpdated;

        mutable bool m_platformRequestUpdated;

        bool m_reportUploadProgress;

        bool m_reportLoadTiming;

        bool m_reportRawHeaders;

        ResourceLoadPriority m_priority;

        TargetType m_targetType;

主要有url, httpMethod, httpHeader, httpBody。

下面以提交sina weibo的表单, 围绕这个ResourceRequest类, 查看它是怎么创建和初始化的。

WebCore::startHTTPRequest() at ResourceHandleSoup.cpp:565 0xc1568d

WebCore::ResourceHandle::start() at ResourceHandleSoup.cpp:667 0xc160f6

WebCore::ResourceHandle::create() at ResourceHandle.cpp:71 0xc0c21d

WebCore::MainResourceLoader::loadNow() at MainResourceLoader.cpp:586 0xac282a

WebCore::MainResourceLoader::load() at MainResourceLoader.cpp:613 0xac2af2

WebCore::DocumentLoader::startLoadingMainResource() at DocumentLoader.cpp:828 0xa7e753

WebCore::FrameLoader::continueLoadAfterWillSubmitForm() at FrameLoader.cpp:2,286 0xa9338d

WebCore::FrameLoader::continueLoadAfterNavigationPolicy() at FrameLoader.cpp:2,807 0xa956df

WebCore::FrameLoader::callContinueLoadAfterNavigationPolicy() at FrameLoader.cpp:2,680 0xa94efa

WebCore::PolicyCallback::call() at PolicyCallback.cpp:103 0xac517b

WebCore::PolicyChecker::continueAfterNavigationPolicy() at PolicyChecker.cpp:164 0xac5f77

webkit_web_policy_decision_use() at webkitwebpolicydecision.cpp:88 0x4c6a74

WebKit::FrameLoaderClient::dispatchDecidePolicyForNavigationAction() at FrameLoaderClientGtk.cpp:608 0x4a1d8a

WebCore::PolicyChecker::checkNavigationPolicy() at PolicyChecker.cpp:89 0xac59d9

WebCore::FrameLoader::loadWithDocumentLoader() at FrameLoader.cpp:1,360 0xa8f56b

WebCore::FrameLoader::load() at FrameLoader.cpp:1,307 0xa8f0b4

WebCore::FrameLoader::load() at FrameLoader.cpp:1,243 0xa8ebc4

WebCore::FrameLoader::load() at FrameLoader.cpp:1,230 0xa8ea22

webkit_web_frame_load_uri() at webkitwebframe.cpp:542 0x4c09c1

webkit_web_view_load_uri() at webkitwebview.cpp:3,835 0x4d784c

main() at main.c:437 0x804b0c6

在WebCore::DocumentLoader::startLoadingMainResource() at DocumentLoader.cpp:828 0xa7e753中DocumentLoader类把自己ResourceRequest放在startLoadingMainResource函数中调用, 可见DocumentLoader维护了这个类。接下来查看DocumentLoader中的ResourceRequest类是如何在DocumentLoader类中创建和初始化的。有两处

DocumentLoader::DocumentLoader(const ResourceRequest& req, const SubstituteData& substituteData)

void DocumentLoader::setRequest(const ResourceRequest& req)

把断点定在这两处

WebCore::DocumentLoader::DocumentLoader() at DocumentLoader.cpp:100 0xa7bd16

WebKit::DocumentLoader::DocumentLoader() at DocumentLoaderGtk.cpp:44 0x48e3df

WebKit::DocumentLoader::create() at DocumentLoaderGtk.h:48 0x4a6f6b

WebKit::FrameLoaderClient::createDocumentLoader() at FrameLoaderClientGtk.cpp:299 0x4a07b2

WebCore::FrameLoader::loadWithNavigationAction() at FrameLoader.cpp:1,264 0xa8ed73

WebCore::FrameLoader::loadPostRequest() at FrameLoader.cpp:2,554 0xa9458b

WebCore::FrameLoader::loadFrameRequest() at FrameLoader.cpp:1,145 0xa8e0cb

WebCore::ScheduledFormSubmission::fire() at NavigationScheduler.cpp:235 0xacaefa

在WebCore::FrameLoader::loadFrameRequest() at FrameLoader.cpp:1,145 0xa8e0cb中调用        loadPostRequest(request.resourceRequest(), referrer, request.frameName(), lockHistory, loadType, event, formState.get());

这个request.resourceRequest()是resourceRequest类型, request是FrameLoadRequest类型。下面要查看FrameLoadRequest在函数fire中有

        FrameLoadRequest frameRequest(requestingFrame->document()->securityOrigin());

        m_submission->populateFrameLoadRequest(frameRequest);

        frame->loader()->loadFrameRequest(frameRequest, lockHistory(), lockBackForwardList(), m_submission->event(), m_submission->state(), SendReferrer);

FrameLoadRequest类是在m_submission->populateFrameLoadRequest(frameRequest);初始化的。查看m_submission是FormSubmission类型, 它有数据

    Method m_method;

    KURL m_action;

    String m_target;

    String m_contentType;

    RefPtr<FormState> m_formState;

    RefPtr<FormData> m_formData;

    String m_boundary;

    bool m_lockHistory;

    RefPtr<Event> m_event;

    String m_referrer;

    String m_origin;

一个    Method m_method;    KURL m_action;RefPtr<FormData> m_formData;

可见它是存储表单数据的类型。这些数据的初始化是在PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, bool lockHistory, FormSubmissionTrigger trigger)

函数中, 一个是HTMLFormElement* form, 另一个是Attributes& attributes。

url来自


formData来自efPtr<DOMFormData> domFormData, 而domFormData来自

    for (unsigned i = 0; i < form->associatedElements().size(); ++i) {

        FormAssociatedElement* control = form->associatedElements()[i];

        HTMLElement* element = toHTMLElement(control);

        if (!element->disabled())

            control->appendFormData(*domFormData, isMultiPartForm);

        if (element->hasLocalName(inputTag)) {

            HTMLInputElement* input = static_cast<HTMLInputElement*>(control);

            if (input->isTextField()) {

                formValues.append(pair<String, String>(input->name().string(), input->value()));

                if (input->isSearchField())

                    input->addSearchResult();

            }

        }

    }

这样一个语句control->appendFormData(*domFormData, isMultiPartForm);它是一个virtual method, 通过跟踪是它是调用了HTMLInputElement类的函数。


class HTMLFormControlElement : public HTMLElement, public FormAssociatedElement 所以HTMLInputElement是HTMLElement又是FormAssociatedElement

HTMLInputElement中有一个Vector<FormAssociatedElement*> m_associatedElements容器, 所以语句中form->associatedElements()[i];取出存放的指针FormAssociatedElement* control, 其实是HTMLInputElement*类型的。在函数control->appendFormData(*domFormData, isMultiPartForm);中把HTMLInputElement数据m_name和m_valueIfDirty(也就是post数据时的name=value)转存出来。得到formData

 通过函数调用stack

WebCore::FormSubmission::create() at FormSubmission.cpp:139 0xa888d2

WebCore::HTMLFormElement::submit() at HTMLFormElement.cpp:336 0x91d3a5

WebCore::HTMLFormElement::submitFromJavaScript() at HTMLFormElement.cpp:298 0x91d1b7

WebCore::jsHTMLFormElementPrototypeFunctionSubmit() at JSHTMLFormElement.cpp:428 0x10b4c82

0x5089cf1

JSC::JITCode::execute() at JITCode.h:80 0x2c0d07c

找到WebCore::jsHTMLFormElementPrototypeFunctionSubmit() at JSHTMLFormElement.cpp:428 0x10b4c82

EncodedJSValue JSC_HOST_CALL jsHTMLFormElementPrototypeFunctionSubmit(ExecState* exec)

{

    JSValue thisValue = exec->hostThisValue();

    if (!thisValue.inherits(&JSHTMLFormElement::s_info))

        return throwVMTypeError(exec);

    JSHTMLFormElement* castedThis = static_cast<JSHTMLFormElement*>(asObject(thisValue));

    ASSERT_GC_OBJECT_INHERITS(castedThis, &JSHTMLFormElement::s_info);

    HTMLFormElement* imp = static_cast<HTMLFormElement*>(castedThis->impl());

    imp->submitFromJavaScript();

    return JSValue::encode(jsUndefined());

}

 找到HTMLFormElement的生成过程。将thisValue.u.asBits.playload转换成JSHTMLFormElement*类型


再将JSHTMLFormElement.JSHTMLElement.JSElement.JSNode.m_impl.m_ptr转换成HTMLFormElement*。就可以得到了。至于thisValuse怎么从exec->hostThisValue();得到, 还不清楚。这个EncodedJSValue JSC_HOST_CALL jsHTMLFormElementPrototypeFunctionSubmit(ExecState* exec)函数怎么被调用的, 在函数栈中找不到调用的语句。。。。那位大牛可以请教???????????????

WebCore::HTMLInputElement::setValue() at HTMLInputElement.cpp:994 0x92c5b8

WebCore::setJSHTMLInputElementValue() at JSHTMLInputElement.cpp:906 0x10c5e27

JSC::lookupPut<WebCore::JSHTMLInputElement>() at Lookup.h:319 0x10c75d9

JSC::lookupPut<WebCore::JSHTMLInputElement, WebCore::JSHTMLElement>() at Lookup.h:333 0x10c72b4

WebCore::JSHTMLInputElement::put() at JSHTMLInputElement.cpp:665 0x10c4fad

JSC::JSValue::put() at JSObject.h:810 0x2c0cc86

JSC::cti_op_put_by_id_generic() at JITStubs.cpp:1,385 0x2c41697

JSC::JITThunks::tryCacheGetByID() at JITStubs.cpp:941 0x2c4095c

0x2ed0ff4

JSC::JITCode::execute() at JITCode.h:80 0x2c0d07c


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值