2

全部

这是一个很少发生的问题。事实上,我不得不花费大量时间来重现它,但无论如何它都在这里。

我正在使用 ASIHTTPRequest 从我的服务器获取一些数据。除了具有 responseStatusCode == 200 的那些之外,我会抛出任何错误。我的服务器返回一些消息。

我注意到的是,有时,根据我的无线连接(在笔记本电脑模拟器的使用情况下),需要身份验证的连接,ASIHttpRequest 返回 200 的响应,但 responseData 类似于以下内容,而不是来自我的服务器的消息

<HTML><HEAD><TITLE>Cisco Systems Inc. Web Authentication Redirect</TITLE><META http-equiv="Cache-control" content="no-cache"><META http-equiv="Pragma" content="no-cache"><META http-equiv="Expires" content="-1"><META http-equiv="refresh" content="1; URL=https://webauth-redirect.oracle.com/login.html?redirect=17.22.111.222/scripts_dummy/messagesx.php"></HEAD></HTML>

它是否正确?如果未收到来自服务器的消息,则 responseStatusCode 不应为 200 以外的值

我该如何处理这种情况?检查 responseStatusCode == 200 后的意思似乎还不够好。这只是一个例子。在其他无线区域,打印出不同的垃圾。

更新 不确定这是否有任何作用,但我有

request.shouldUseRFC2616RedirectBehaviour = YES; // where request is ASIHTTPRequest
4

3 回答 3

3

那不是ASIHTTPRequest你的客户代码的错。那是服务器期望客户端是 Web 浏览器并向其发送元刷新重定向(即,其中嵌入了重定向的 HTML 页面)而不是HTTP 30x,它ASIHTTP会为您处理。

这是元刷新被滥用的一个很好的例子:它本来是用来刷新当前页面的,但人们开始使用它来将客户端发送到其他地方,而这正是 HTTP 30x 的设计初衷。谷歌搜索“元刷新与 301 重定向”会给你大量的博客文章来争论。

在您的情况下,除非您可以让您的服务器对非浏览器客户端表现得更友好,否则当响应代码为 200 时,您需要自己检查这种情况,解析重定向并自己重新发出请求。

于 2012-05-06T00:26:55.133 回答
1

在考虑了一些之后,我想出了一个替代策略。内容类型将被保留,不应混淆。

您应该能够将内容类型用作您正在接收代理注入页面的标志。设置内容类型参数,然后让您的应用程序关闭该参数。任何没有参数的响应都是无效的。

$content_type = 'text/html; FooCorp-MyApp=true'

顺便说一句:如果您不正确支持 HTML 处理,为什么要使用 text/html 的内容类型。元刷新应该是任何 HTML 引擎的一部分。如果您不需要 HTML,您可能需要考虑使用特定于数据的内容类型,例如 XML、YAML 或 JSON。


问题已经提出,“这有效吗?”

来自RFC 2616:3.7 媒体类型

类型、子类型和参数属性名称不区分大小写。参数值可能区分大小写,也可能不区分大小写,具体取决于参数名称的语义。线性空白 (LWS) 不得在类型和子类型之间使用,也不得在属性与其值之间使用。参数的存在与否对于媒体类型的处理可能很重要,这取决于它在媒体类型注册表中的定义。

请注意,一些较旧的 HTTP 应用程序无法识别媒体类型参数。当向旧的 HTTP 应用程序发送数据时,实现应该只在该类型/子类型定义需要时使用媒体类型参数。

对我来说,这样做的好处是不要向老客户发送非标准参数。在上下文中,如果您将其发送给自 2000 年以来的任何客户,这意味着您是安全的。

于 2012-05-16T13:18:30.917 回答
0

我最终在响应标头中传递了一个特殊的键/值对,以确保客户端了解响应来自我的服务器而不是来自某些中间重定向。

function sendResponse($status = 200, $body = '', $content_type = 'text/html')
{
   $status_header = 'HTTP/1.1 ' . $status . ' ' . getStatusCodeMessage($status);
   header($status_header);
   header('Content-type: ' . $content_type);
   $value = 'success';
   header('myApp:' . $value); // --> I will always check in my client that the key myApp has the value success

echo $body;
}
于 2012-05-12T02:11:55.610 回答