簡體   English   中英

PHP 中沒有從 cURL POST 到 REST API 的 XML 響應

[英]No XML response from cURL POST to REST API in PHP

我正在通過 cURL 將 PHP 中的 POST 請求發送到使用 XML 的 REST API。 當我使用 Postman 或 Advanced REST Client 時,我會收到對我的 POST 請求的 XML 響應。 但是,當我使用 PHP 和 cURL 時,我似乎看不到 XML 響應。 我需要做什么才能取回這些? 最終,我需要檢索一個令牌,然后我可以使用該令牌通過 XML 通過此 API 處理 INSERT、UPDATES 和 GETS。

這是我目前使用的代碼:

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_HTTPHEADER => array(
    'xxxxxx-Username: xxx',
    'xxxxxx-Password: xxx',
    'content-type: application/xml'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

目前我得到了一個空白頁。 我嘗試了很多解決方案,如下所示

//header("Content-Type: text/xml");
//header('Content-type: application/xml');
//$decoded = iconv("UTF-8", "ISO-8859-1//TRANSLIT", $response);
//echo $decoded;

//echo $response;
//print_r($response);

// set up your xml result
$xml = new SimpleXMLElement($response, LIBXML_NOCDATA);

// loop through the results
$cnt = count($xml->Result);
for($i=0; $i<$cnt; $i++){
    echo 'XML : First Name: = ';
}

但似乎沒有什么可以給我回我從 Postman 或 Advanced REST Client 得到的東西,在這個特定的命令中如下

<?xml version="1.0" encoding="UTF-8"?>
<AuthInfo>
    <token/>
    <AuthStatus>
        <Id>503</Id>
        <Description>There's no proapi manager running with the given company code: crmapp</Description>
    </AuthStatus>
</AuthInfo>

我知道在這個階段我的 url 有問題需要修復,但我仍然應該能夠通過 XML 接收到該錯誤。

任何人都可以幫我取回這個 XML 響應,以便我可以改進我的界面嗎?

提前謝謝你,阿德里

再次感謝教授,這是最新版本的PHP和cUrl的完整調試

Verbose debug info

*   Trying xxx.xx.xxx.xxx:443...
* Connected to xxxxx-xx-xx.xxxxxxxx.com.au (xxx.xx.xxx.xxx) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: D:/Adri/PHP/MoW/famac/cacert.pem
*  CApath: D:/Adri/PHP/MoW/famac/cacert.pem
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=*.prontohosted.com.au
*  start date: Jun  2 00:00:00 2020 GMT
*  expire date: Sep  4 00:00:00 2022 GMT
*  subjectAltName: host "xxxxx-xx-xx.xxxxxxxx.com.au" matched cert's "*.xxxxxxxx.com.au"
*  issuer: C=GB; ST=Greater Manchester; L=Salford; O=Sectigo Limited; CN=Sectigo RSA Domain Validation Secure Server CA
*  SSL certificate verify ok.
> GET /xxxxx/rest/xxx.xxx/login HTTP/1.1
Host: xxxxx-xx-xx.xxxxxxxx.com.au
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.38 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.38
Accept: */*
Accept-Encoding: deflate, gzip
xxxxxx-Username: xxx
xxxxxx-Password: xxx
Content-Type: application/xml

* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< Date: Tue, 09 Nov 2021 11:34:57 GMT
< Server: Apache
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Content-Security-Policy: img-src 'self' *.xxxxx.net *.xxxxx.com.au https://www.google.com https://*.googleapis.com/ www.google-analytics.com stats.g.doubleclick.net http://*.xxxxx-xxxxx.com *.twitter.com *.twimg.com data: blob: https://*.google.com https://*.gstatic.com https://*.googleapis.com; frame-src * blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.xxxxx.net *.xxxxx.com.au https://*.google.com www.google-analytics.com *.twitter.com *.twimg.com  https://*.googleapis.com https://jawj.github.io https://*.gstatic.com; connect-src 'self' wss: blob: *.twitter.com www.google-analytics.com stats.g.doubleclick.net; base-uri 'none'; style-src 'self' 'unsafe-inline' *.twitter.com *.twimg.com https://*.google.com *.googleapis.com https://*.gstatic.com; font-src 'self' data: https://*.googleapis.com https://fonts.gstatic.com; child-src * blob:; object-src 'none'; default-src 'self' blob:
< X-Permitted-Cross-Domain-Policies: master-only
< Content-Type: text/html; charset=UTF-8
< Content-Length: 994
* The requested URL returned error: 404
* Closing connection 0

Info

stdClass Object
(
    [url] => https://xxxxx-xx-xx.xxxxxxxx.com.au/xxxxx/rest/xxx.xxx/login
    [content_type] => text/html; charset=UTF-8
    [http_code] => 404
    [header_size] => 1271
    [request_size] => 350
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.232624
    [namelookup_time] => 0.029367
    [connect_time] => 0.05058
    [pretransfer_time] => 0.162497
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => 994
    [upload_content_length] => 0
    [starttransfer_time] => 0.232609
    [redirect_time] => 0
    [redirect_url] => 
    [primary_ip] => xxx.xx.xxx.xxx
    [certinfo] => Array
        (
        )

    [primary_port] => 443
    [local_ip] => xxx.xxx.x.xxx
    [local_port] => 52711
    [http_version] => 2
    [protocol] => 2
    [ssl_verifyresult] => 0
    [scheme] => HTTPS
    [appconnect_time_us] => 162464
    [connect_time_us] => 50580
    [namelookup_time_us] => 29367
    [pretransfer_time_us] => 162497
    [redirect_time_us] => 0
    [starttransfer_time_us] => 232609
    [total_time_us] => 232624
)

你能告訴我你對這件事的看法嗎? 雖然我不再收到以前的錯誤,但我似乎仍然無法收到 XML 響應。 :(

提前謝謝你,阿德里

我使用的curl函數如下。 它在輸出中有額外的調試信息,並且可以通過提供不同的$options參數在運行時輕松覆蓋默認設置。 我並不是在暗示這是答案,但是通過配置更好的選項集和更好的調試信息,您應該更接近。

function curl( $url=NULL, $options=NULL, $headers=false ){
    $cacert='c:/wwwroot/cacert.pem';
    $vbh = fopen('php://temp', 'w+');
    /*
        Download a copy of CACERT.pem from
        https://curl.haxx.se/docs/caextract.html
        
        save to webserver and modify the $cacert variable
        to suit - ensuring that the path you choose is
        readable.
    */
    
    $res=array(
        'response'  =>  NULL,
        'info'      =>  array( 'http_code' => 100 ),
        'headers'   =>  NULL,
        'errors'    =>  NULL
    );
    if( is_null( $url ) ) return (object)$res;

    session_write_close();

    /* Initialise curl request object - these should be OK as-is */
    $curl=curl_init();
    if( parse_url( $url,PHP_URL_SCHEME )=='https' ){
        curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, true );
        curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 2 );
        curl_setopt( $curl, CURLOPT_CAINFO, $cacert );
        curl_setopt( $curl, CURLOPT_CAPATH, $cacert );
    }

    /* Define standard options */
    curl_setopt( $curl, CURLOPT_URL,trim( $url ) );
    curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
    curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
    curl_setopt( $curl, CURLOPT_FAILONERROR, true );
    curl_setopt( $curl, CURLOPT_HEADER, false );
    curl_setopt( $curl, CURLINFO_HEADER_OUT, false );
    curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true );
    curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 20 );
    curl_setopt( $curl, CURLOPT_TIMEOUT, 60 );
    curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.38 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.38' );
    curl_setopt( $curl, CURLOPT_MAXREDIRS, 10 );
    curl_setopt( $curl, CURLOPT_ENCODING, '' );
    
    /* enhanced debug */
    curl_setopt( $curl, CURLOPT_VERBOSE, true );
    curl_setopt( $curl, CURLOPT_NOPROGRESS, true );
    curl_setopt( $curl, CURLOPT_STDERR, $vbh );
    

    /* Assign runtime parameters as options to override defaults if needed. */
    if( isset( $options ) && is_array( $options ) ){
        foreach( $options as $param => $value ) curl_setopt( $curl, $param, $value );
    }
    /* send any headers with the request that are needed */
    if( $headers && is_array( $headers ) ){
        curl_setopt( $curl, CURLOPT_HTTPHEADER, $headers );
    }

    /* Execute the request and store responses */
    $res=(object)array(
        'response'  =>  curl_exec( $curl ),
        'info'      =>  (object)curl_getinfo( $curl ),
        'errors'    =>  curl_error( $curl )
    );
    rewind( $vbh );
    $res->verbose=stream_get_contents( $vbh );
    fclose( $vbh );
    curl_close( $curl );
    return $res;
}

然后,使用它:

$url='https://www.example.com/api/';
$args=array();
$headers=array(
    'xxxxxx-Username: xxx',
    'xxxxxx-Password: xxx',
    'Content-Type: application/xml'
);

$res=curl( $url, $args, $headers );
if( $res->info->http_code==200 ){
    #cool - use $res->response in further processing
    print_r($res->response,true);
}else{
    # useful information will be displayed here...
    printf('<h1>Verbose debug info</h1><pre>%s</pre>',print_r($res->verbose,true));
    printf('<h1>Info</h1><pre>%s</pre>',print_r($res->info,true));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM