UIWebView 中 PUT 或 POST 类型的 ajax 不通过 HTTP 正文

Posted

技术标签:

【中文标题】UIWebView 中 PUT 或 POST 类型的 ajax 不通过 HTTP 正文【英文标题】:ajax of type PUT or POST in UIWebView does not pass HTTP body 【发布时间】:2013-11-11 15:25:21 【问题描述】:

我正在我的应用程序的 UIWebView 中打开一个简单的 html 文档:

<h3>Testing Put</h3>
<form id="testPut" action="onPut">
    <div>
        <p><input type="text" id="putValue" name="putValue" value="some value string goes here" size="100"/></p>
        <p><input type="submit" value="Submit via PUT"/></p>
    </div>
</form>

<script>
$('#testPut').submit(function(ev) 
    ev.preventDefault();
    var value = $('#putValue').val();

    $.ajax(
        type: "PUT",
        url: "data/info/put",
        contentType: "text/plain; charset=utf-8",
        data: encodeURIComponent(value),
        dataType: "text"
    );
);
</script>

为了简单起见,我在代码中省略了成功和错误处理程序,因为我的问题与真正回复请求无关。

我使用的是 jQuery 1.10.2,但是在使用纯 XMLHttpRequest 对象时得到完全相同的结果。

由于UIWebViewDelegate 方法无法捕获 Ajax 请求这一已知问题,我决定创建一个非常简单的 NSURLProtocol 后代并将其注册到我的控制器的 -viewDidLoad 方法中:

@implementation MyProtocol

+ (BOOL)canInitWithRequest:(NSURLRequest *)request 
    // only "data/info" requests are welcome
    NSRange range = [[request.URL absoluteString] rangeOfString:@"data/info"];
    return NSNotFound != range.location;


+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request 
    return request;


- (void)startLoading 
    NSURLRequest *request = self.request;

    NSLog(@"%@", request);
    NSLog(@"Headers: %@", [request allHTTPHeaderFields]);
    NSLog(@"Method: %@", [request HTTPMethod]);
    NSLog(@"Body: %@", [request HTTPBody]);


- (void)stopLoading 

@end

然后我运行应用程序,点击“通过 PUT 提交”按钮并在 Xcode 的控制台日志中观察以下内容:

2013-10-31 16:38:28.077 TestHTTPPUTios[1608:4a03] <NSURLRequest: 0x8942c20>  URL: file:///Users/oradyvanyuk/Library/Application%20Support/iPhone%20Simulator/7.0.3/Applications/90232D0E-3243-4517-A2B7-15A17371E117/TestHTTPPUTiOS.app/data/info/put 
2013-10-31 16:38:28.079 TestHTTPPUTiOS[1608:4a03] Headers: 
    Accept = "text/plain, */*; q=0.01";
    "Content-Type" = "text/plain; charset=utf-8";
    Origin = "file://";
    "X-Requested-With" = XMLHttpRequest;

2013-10-31 16:38:28.079 TestHTTPPUTiOS[1608:4a03] Method: PUT
2013-10-31 16:38:28.080 TestHTTPPUTiOS[1608:4a03] Body: (null)

如您所见,HTTP 请求正文为空。我尝试过使用 POST 方法并得到完全相同的输出,唯一的区别是控制台中的 Method: POST

使用 GET 方法时,我也会得到空的 HTTP 正文,但实际上这是意料之中的,因为表单中的 putValue 字符串到达​​了 HTTP 请求的 URL。

您能否就这个问题提出建议,或者至少告诉我我是否做错了什么?我需要将传递的值作为 HTTP 正文内容而不是在 URL 中获取,因为它可能很长。

【问题讨论】:

【参考方案1】:

您可以为您的 AJAX 调用尝试以下方法吗?

$.ajax(
    type: "POST",
    url: "data/info/put",
    data: 'key='+encodeURIComponent(value),
    dataType: "text"
);

我在您的具体示例中尝试了一系列组合和设置,这是唯一能够按预期可靠发送数据的组合和设置(即通过删除 contentType 规范并将请求类型从 PUT 更改为 POST)。另外,请注意,并非所有浏览器都支持 PUT,因此除非出于某些关键原因使用它而不是 POST,否则您可能不应该使用它。

【讨论】:

刚刚尝试了您的建议,但效果不佳。无论您在“数据”属性中指定什么,都无法到达它应该在的 HTTP 正文。如果指定的话,“contentType”的值是多少并不重要。 我怀疑 WebKit 实现中存在错误。我已经向 Apple 的 bugtracker 发布了一个错误报告,到目前为止它仍处于 Open 状态。我希望这个问题会在即将发布的 iOS 版本中得到解决。

以上是关于UIWebView 中 PUT 或 POST 类型的 ajax 不通过 HTTP 正文的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 React Native POST 或 PUT 原始二进制文件

asp.net mvc 和 web api 哪个更好 Http POST 或 PUT

thinkphp 判断请求类型

thinkphp3.2 请求怎么发送 put

POST与PUT

ajax中的put请求和post请求传data值的区别