XHR: Add responseURL
https://xhr.spec.whatwg.org/#the-responseurl-attribute the attribute was introduced around 2014. [ChangeLog][Qml][XMLHttpRequest] Added missing responseURL property. This returns the url that was used to retrieve the response data, after any redirects have occurred. Change-Id: Ice70520913bb306885a10dfd7a3a89da31bcfdeb Task-number: QTBUG-111217 Reviewed-by: Lars Knoll <lars@knoll.priv.no>
This commit is contained in:
parent
3991a2e8ca
commit
efc037191a
|
@ -223,6 +223,13 @@
|
|||
\sa {XMLHttpRequest::onreadystatechange}{onreadystatechange}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty string XMLHttpRequest::responseURL
|
||||
\readonly
|
||||
|
||||
Returns the url that was used to retrieve the response data, after any redirects have occurred.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty string XMLHttpRequest::responseText
|
||||
\readonly
|
||||
|
|
|
@ -998,6 +998,7 @@ public:
|
|||
QString responseBody();
|
||||
const QByteArray & rawResponseBody() const;
|
||||
bool receivedXml() const;
|
||||
QUrl url() const;
|
||||
|
||||
const QString & responseType() const;
|
||||
void setResponseType(const QString &);
|
||||
|
@ -1162,6 +1163,7 @@ void QQmlXMLHttpRequest::fillHeadersList()
|
|||
|
||||
void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
|
||||
{
|
||||
m_url = url;
|
||||
QNetworkRequest request = m_request;
|
||||
|
||||
if (QQmlFile::isLocalFile(url)) {
|
||||
|
@ -1462,6 +1464,11 @@ bool QQmlXMLHttpRequest::receivedXml() const
|
|||
return m_gotXml;
|
||||
}
|
||||
|
||||
QUrl QQmlXMLHttpRequest::url() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
const QString & QQmlXMLHttpRequest::responseType() const
|
||||
{
|
||||
return m_responseType;
|
||||
|
@ -1666,6 +1673,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
|
|||
static ReturnedValue method_get_response(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
|
||||
static ReturnedValue method_get_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
|
||||
static ReturnedValue method_set_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
|
||||
static ReturnedValue method_get_responseURL(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1714,6 +1722,7 @@ void QQmlXMLHttpRequestCtor::setupProto()
|
|||
p->defineAccessorProperty(QStringLiteral("responseText"),method_get_responseText, nullptr);
|
||||
p->defineAccessorProperty(QStringLiteral("responseXML"),method_get_responseXML, nullptr);
|
||||
p->defineAccessorProperty(QStringLiteral("response"),method_get_response, nullptr);
|
||||
p->defineAccessorProperty(QStringLiteral("responseURL"),method_get_responseURL, nullptr);
|
||||
|
||||
// Read-write properties
|
||||
p->defineAccessorProperty(QStringLiteral("responseType"), method_get_responseType, method_set_responseType);
|
||||
|
@ -2039,6 +2048,24 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(const FunctionObje
|
|||
return Encode::undefined();
|
||||
}
|
||||
|
||||
ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseURL(const FunctionObject *b, const Value *thisObject, const Value *, int)
|
||||
{
|
||||
Scope scope(b);
|
||||
Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
|
||||
if (!w)
|
||||
V4THROW_REFERENCE("Not an XMLHttpRequest object");
|
||||
QQmlXMLHttpRequest *r = w->d()->request;
|
||||
|
||||
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
|
||||
r->readyState() != QQmlXMLHttpRequest::Done) {
|
||||
return Encode(scope.engine->newString(QString()));
|
||||
} else {
|
||||
QUrl url = r->url();
|
||||
url.setFragment(QString());
|
||||
return Encode(scope.engine->newString(url.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void qt_rem_qmlxmlhttprequest(ExecutionEngine * /* engine */, void *d)
|
||||
{
|
||||
QQmlXMLHttpRequestData *data = (QQmlXMLHttpRequestData *)d;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
QtObject {
|
||||
property string url
|
||||
property string expectedURL
|
||||
|
||||
property bool dataOK: false
|
||||
|
||||
Component.onCompleted: {
|
||||
var x = new XMLHttpRequest;
|
||||
|
||||
x.open("GET", url);
|
||||
x.setRequestHeader("Accept-Language", "en-US");
|
||||
|
||||
// Test to the end
|
||||
x.onreadystatechange = function() {
|
||||
if (x.readyState === XMLHttpRequest.DONE) {
|
||||
dataOK = (x.responseURL === expectedURL);
|
||||
}
|
||||
}
|
||||
|
||||
x.send()
|
||||
}
|
||||
}
|
||||
|
|
@ -75,6 +75,7 @@ private slots:
|
|||
void statusText_data();
|
||||
void responseText();
|
||||
void responseText_data();
|
||||
void responseURL();
|
||||
void responseXML_invalid();
|
||||
void invalidMethodUsage();
|
||||
void redirects();
|
||||
|
@ -1025,6 +1026,64 @@ void tst_qqmlxmlhttprequest::responseText_data()
|
|||
QTest::newRow("Internal server error") << testFileUrl("status.500.reply") << testFileUrl("testdocument.html") << "QML Rocks!\n";
|
||||
}
|
||||
|
||||
|
||||
void tst_qqmlxmlhttprequest::responseURL()
|
||||
{
|
||||
// 200 OK
|
||||
{
|
||||
TestHTTPServer server;
|
||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
||||
QVERIFY(server.wait(testFileUrl("status.expect"),
|
||||
testFileUrl("status.200.reply"),
|
||||
testFileUrl("testdocument.html")));
|
||||
|
||||
QQmlComponent component(engine.get(), testFileUrl("responseURL.qml"));
|
||||
QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
|
||||
QVERIFY(!object.isNull());
|
||||
object->setProperty("url", server.urlString("/testdocument.html"));
|
||||
object->setProperty("expectedURL", server.urlString("/testdocument.html"));
|
||||
component.completeCreate();
|
||||
|
||||
QTRY_VERIFY(object->property("dataOK").toBool());
|
||||
}
|
||||
|
||||
// 200 OK with the exclude fragment flag set
|
||||
{
|
||||
TestHTTPServer server;
|
||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
||||
QVERIFY(server.wait(testFileUrl("status.expect"),
|
||||
testFileUrl("status.200.reply"),
|
||||
testFileUrl("testdocument.html")));
|
||||
|
||||
QQmlComponent component(engine.get(), testFileUrl("responseURL.qml"));
|
||||
QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
|
||||
QVERIFY(!object.isNull());
|
||||
object->setProperty("url", server.urlString("/testdocument.html#fragment"));
|
||||
object->setProperty("expectedURL", server.urlString("/testdocument.html"));
|
||||
component.completeCreate();
|
||||
|
||||
QTRY_VERIFY(object->property("dataOK").toBool());
|
||||
}
|
||||
|
||||
// 302 Found
|
||||
{
|
||||
TestHTTPServer server;
|
||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
||||
server.addRedirect("redirect.html", server.urlString("/redirecttarget.html"));
|
||||
server.serveDirectory(dataDirectory());
|
||||
|
||||
QQmlComponent component(engine.get(), testFileUrl("responseURL.qml"));
|
||||
QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
|
||||
QVERIFY(!object.isNull());
|
||||
object->setProperty("url", server.urlString("/redirect.html"));
|
||||
object->setProperty("expectedURL", server.urlString("/redirecttarget.html"));
|
||||
component.completeCreate();
|
||||
|
||||
QTRY_VERIFY(object->property("dataOK").toBool());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tst_qqmlxmlhttprequest::nonUtf8()
|
||||
{
|
||||
QFETCH(QString, fileName);
|
||||
|
|
Loading…
Reference in New Issue