iPhone - 当“'&'”时出现奇怪的行为包含在 HTTP 请求正文中

发布于 2025-01-08 21:40:59 字数 2427 浏览 0 评论 0原文

我遇到了一个与从 iPhone 应用程序发送 POST 请求相关的非常奇怪的问题。

应用程序需要将 HTTP post 数据发送到第三方服务。请求是 XML,它将得到 XML 响应。这是我发送请求的代码:

-(void)sendRequest:(NSString *)aRequest
{
    //aRequest parameter contains the XML string to send.
    //this string is already entity-encoded
    isDataRequest = NO;
    //the following line will created string REQUEST=<myxml>
    NSString *httpBody =  [NSString stringWithFormat:@"%@=%@",requestString,aRequest];
    //I'm not sure what this next string is doing, frankly, as I didn't write this code initially
    httpBody = [(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)httpBody, NULL, CFSTR("+"), kCFStringEncodingUTF8) autorelease];   
    NSData *aData = [httpBody dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:kOOURLRequest]] autorelease]; 
    [request setHTTPBody:aData];
    [request setHTTPMethod:@"POST"];
    self.feedURLConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
}

只要请求 XML 不包含 & 符号,该代码就可以正常工作,例如,此 XML 请求:

<?xml version="1.0"?>
<request type="search" group="0" language="en" version="2.5.2">
    <auth>
        <serial>623E1579-AC18-571B-9022-3659764542E7</serial>
    </auth>
    <data>
        <location>
            <lattitude>51.528536</lattitude>
            <longtitude>-0.108865</longtitude>
        </location>
        <search>archive</search>
    </data>
</request>

按预期发送并收到正确的响应正如预期的那样。

但是,当请求包含 & 字符(特别是在“search”元素中)时 - 如下所示:

<?xml version="1.0"?>
<request type="search" group="0" language="en" version="2.5.2">
    <auth>
        <serial>623E1579-AC18-571B-9022-3659764542E7</serial>
    </auth>
    <data>
        <location>
            <lattitude>51.528536</lattitude>
            <longtitude>-0.108865</longtitude>
        </location>
        <search>&amp; archive</search>
    </data>
</request>

只有 & 字符之前的所有内容都会发送到服务器。服务器似乎没有收到除此字符之外的任何内容。请注意,我在 Android 应用程序中运行了几乎相同的代码,并且一切正常,因此这在服务器上不是问题。

任何如何解决这个问题的想法将不胜感激!

I've got a very strange problem related to sending POST request from my iPhone app.

The app needs to send the HTTP post data to a third-party service. Request is XML and it'll get XML response. Here's my code for sending the request:

-(void)sendRequest:(NSString *)aRequest
{
    //aRequest parameter contains the XML string to send.
    //this string is already entity-encoded
    isDataRequest = NO;
    //the following line will created string REQUEST=<myxml>
    NSString *httpBody =  [NSString stringWithFormat:@"%@=%@",requestString,aRequest];
    //I'm not sure what this next string is doing, frankly, as I didn't write this code initially
    httpBody = [(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)httpBody, NULL, CFSTR("+"), kCFStringEncodingUTF8) autorelease];   
    NSData *aData = [httpBody dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:kOOURLRequest]] autorelease]; 
    [request setHTTPBody:aData];
    [request setHTTPMethod:@"POST"];
    self.feedURLConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
}

This works perfectly well as long as the request XML doesn't contain & symbol, for example, this XML request:

<?xml version="1.0"?>
<request type="search" group="0" language="en" version="2.5.2">
    <auth>
        <serial>623E1579-AC18-571B-9022-3659764542E7</serial>
    </auth>
    <data>
        <location>
            <lattitude>51.528536</lattitude>
            <longtitude>-0.108865</longtitude>
        </location>
        <search>archive</search>
    </data>
</request>

is sent as expected and the correct response is received as expected.

However, when the request contains & character (specifically in the "search" element) - like so:

<?xml version="1.0"?>
<request type="search" group="0" language="en" version="2.5.2">
    <auth>
        <serial>623E1579-AC18-571B-9022-3659764542E7</serial>
    </auth>
    <data>
        <location>
            <lattitude>51.528536</lattitude>
            <longtitude>-0.108865</longtitude>
        </location>
        <search>& archive</search>
    </data>
</request>

Only everything up to the & character is sent to the server. The server doesn't seem to receive anything beyond this character. Note that I have a pretty much the same code working in an Android app and everything is working correctly, so it's not a problem on the server.

Any ideas how I can get this fixed would be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

姜生凉生 2025-01-15 21:40:59

感谢Zaph的评论,我终于解决了。我使用 WireShark 查看实际发送到服务器的内容,发现请求未完全编码。在最终的 HTTP 正文中,存在实际符号 && 的一部分)。这在服务器端自然不能很好地工作,因为它接收到如下内容:

REQUEST=first_half_of_request&second_half_of_request

当服务器解码 POST 变量时,& 被视为变量的分隔符,因此 REQUEST 变量是仅设置为first_half_of_request - 直到 & 字符的所有内容。

解决方案非常简单。在行中将

httpBody = [(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)httpBody, NULL, CFSTR("+"), kCFStringEncodingUTF8) autorelease];

CFSTR("+") 替换为 CFSTR("+&") 以对 & 进行编码。现在,与实体编码(& for &)相结合,可以将正确的数据发送到服务器并接收到正确的响应。

Thanks to Zaph's comment, I finally sorted it. I used WireShark to see what was actually sent to the server and discovered that the request wasn't encoded completely. In the final HTTP body the actual symbol & was present (part of &). This naturally didn't work very well on the server side, because it was receiving something like:

REQUEST=first_half_of_request&second_half_of_request

When the server decoded the POST variables, & was taken as the separator of variables, therefore the REQUEST variable was only set to the first_half_of_request - everything up to the & char.

The solution was quite simple. In line

httpBody = [(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)httpBody, NULL, CFSTR("+"), kCFStringEncodingUTF8) autorelease];

replace CFSTR("+") with CFSTR("+&") to encode & as well. Now this, combined with entity encoding (& for &), resulted in the correct data being sent to the server and the correct response being received.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文