11

编辑:我已经根据从人们那里得到的所有建议编辑了 OP,所以这是最新的(并且仍然无法正常工作)。


我有以下代码,它应该将一些数据发布到我拥有的 .php 文件中(然后发布到数据库,但这超出了这个问题的范围)。

对于我的方法,我传递了一个包含一些字符串的数组。

-(void)JSON:(NSArray *)arrayData {

    //parse out the json data
    NSError *error;

    //convert array object to data
    NSData* JSONData = [NSJSONSerialization dataWithJSONObject:arrayData 
                                                       options:NSJSONWritingPrettyPrinted 
                                                         error:&error];

    NSString *JSONString = [[NSString alloc] initWithData:JSONData 
                                                 encoding:NSUTF8StringEncoding];


    NSString *URLString = [NSString stringWithFormat:@"websitename"];

    NSURL *URL = [NSURL URLWithString:URLString];

    NSLog(@"URL: %@", URL);


    NSMutableURLRequest *URLRequest = [NSMutableURLRequest requestWithURL:URL 
                                                              cachePolicy:NSURLRequestUseProtocolCachePolicy 
                                                          timeoutInterval:60.0];

    NSData *requestData = [NSData dataWithBytes:[JSONString UTF8String] length:[JSONString length]];

    NSString *requestDataString = [[NSString alloc] initWithData:requestData 
                                                        encoding:NSUTF8StringEncoding];
    NSLog(@"requestData: %@", requestDataString);

    [URLRequest setHTTPMethod:@"POST"];
    NSLog(@"method: %@", URLRequest.HTTPMethod);
    [URLRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [URLRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [URLRequest setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
    [URLRequest setHTTPBody: requestData];

    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:URLRequest delegate:self];

    if (connection) {
        NSMutableData *receivedData = [[NSMutableData data] retain];
        NSString *receivedDataString = [[NSString alloc] initWithData:receivedData 
                                                             encoding:NSUTF8StringEncoding];
        NSLog(@"receivedData: %@", receivedDataString);
    }

    //potential response
    NSData *response = [NSURLConnection sendSynchronousRequest:URLRequest returningResponse:nil error:nil];

    //convert response so that it can be LOG'd
    NSString *returnString = [[NSString alloc] initWithData:response encoding:NSASCIIStringEncoding];

    NSLog(@"RETURN STRING: %@", returnString);
}

注意:我在代码中有我网站的实际 URL,以便任何人都可以测试是否愿意。


然后是 .php 方面的事情,我所要做的就是寻找任何输入(但我什么也没得到)。

<html>
        <body>
        <?php

        echo "Connection from iOS app to MySQL database<BR>";

        echo '<pre>'.print_r($GLOBALS,true).'</pre>';



        ?>
        </body>
</html>

我现在真正想做的就是确认数据正在通过,通过将其回显到页面,然后从我的应用程序中读取页面(到目前为止数据尚未显示)。


.php 的输出:

 <html>
        <body>
        Connection from iOS app to MySQL database<BR>'Array
(
)
'<pre>Array
(
    [_GET] => Array
        (
        )

    [_POST] => Array
        (
        )

    [_COOKIE] => Array
        (
        )

    [_FILES] => Array
        (
        )

    [GLOBALS] => Array
 *RECURSION*
)
</pre>        </body>
</html>
4

3 回答 3

10

您正在发布 JSON 而不是application/x-www-form-urlencoded.

PHP$_POST仅用于 -requestsapplication/x-www-form-urlencoded。如果您像这样直接发送 json,那么您应该这样做:

<?php
$posted_json = json_decode(file_get_contents("php://input"));
print_r($posted_json);

请注意,如果 json 无效,这将不起作用。您始终可以使用以下命令调试请求正文:

<?php
echo file_get_contents("php://input");

这是 $_POST 和 $_GET http://www.php.net/manual/en/language.variables.external.php的一般解释:

它们旨在与普通的 html 表单一起使用,尽管您可以使用适当的编码和内容类型标头轻松模拟此类请求。但它们不适用于 JSON,因为这不是普通的 html 表单的工作方式。

于 2012-08-13T13:50:07.223 回答
8

我对Objective-C一无所知,假设您正在尝试发送以下JSON数据(即JSONString如下):

{
    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "address": {
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state": "NY",
        "postalCode": "10021"
    },
    "phoneNumber": [
        {
            "type": "home",
            "number": "212 555-1234"
        },
        {
            "type": "fax",
            "number": "646 555-4567"
        }
    ]
}

那么你的请求应该是这样的:

POST /yourwebsite.php HTTP/1.1
Host: cs.dal.ca
User-Agent: USER-AGENT
Accept: text/html,application/json,*/*
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 624

data=%7B%0A++++%22firstName%22%3A+%22John%22%2C%0A++++%22lastName%22%3A+%22Smith%22%2C%0A++++%22age%22%3A+25%2C%0A++++%22address%22%3A+%7B%0A++++++++%22streetAddress%22%3A+%2221+2nd+Street%22%2C%0A++++++++%22city%22%3A+%22New+York%22%2C%0A++++++++%22state%22%3A+%22NY%22%2C%0A++++++++%22postalCode%22%3A+%2210021%22%0A++++%7D%2C%0A++++%22phoneNumber%22%3A+%5B%0A++++++++%7B%0A++++++++++++%22type%22%3A+%22home%22%2C%0A++++++++++++%22number%22%3A+%22212+555-1234%22%0A++++++++%7D%2C%0A++++++++%7B%0A++++++++++++%22type%22%3A+%22fax%22%2C%0A++++++++++++%22number%22%3A+%22646+555-4567%22%0A++++++++%7D%0A++++%5D%0A%7D%0A%0A%0A

请注意,这Content-Type: application/json不是您使用过的发布数据的方式,并注意数据已被urlencoded,这应该不难,我在 Objective-C 中找到了关于这样做的链接:URLEncoding a string with Objective-C

发送上述请求,我得到了这个:

php代码:

<?php
$raw_json_data = $_POST['data'];
$json_data = json_decode($raw_json_data);
print_r($json_data);

结果:

stdClass Object
(
    [firstName] => John
    [lastName] => Smith
    [age] => 25
    [address] => stdClass Object
        (
            [streetAddress] => 21 2nd Street
            [city] => New York
            [state] => NY
            [postalCode] => 10021
        )

    [phoneNumber] => Array
        (
            [0] => stdClass Object
                (
                    [type] => home
                    [number] => 212 555-1234
                )

            [1] => stdClass Object
                (
                    [type] => fax
                    [number] => 646 555-4567
                )

        )

)

这就是你想要的!

注意:我应该提到您在http://yourwebsite.php的脚本无法正常工作,我什至无法向它提交正常的表单!可能存在服务器配置错误或类似问题,但使用 Apache 2.2 和 PHP 5.4.4 以及上面提到的代码,我得到了它的工作!

于 2012-08-16T12:52:51.057 回答
2

您已接受 http 标头字段设置为application/json。内容类型也是如此。您可能需要检查在浏览器和服务器之间传递的数据是否是有效的 json。您也可以将其更改为text/plain并检查..

于 2012-08-09T21:15:52.783 回答