要約: http リクエストで 400 エラーが発生する場合、通常は無効な http リクエスト (不正なリクエスト) と不正な URL パラメータのエンコード形式が原因です。 URL には特定の形式要件があり、URL を使用するには、英字、アラビア数字、およびスペースや二重引用符などの一部の特殊文字のみを使用できます。 1. ブラウザで直接アクセスする場合、ブラウザが自動的にエンコード処理を行います。 2. ただし、プログラム内で直接呼び出す場合、たとえば、curl_exec を使用して PHP を呼び出す場合、URL は事前にエンコードされる必要があります。スペースはエンコードする必要があるため。 3. 特に、url パラメーターに含まれる json データ値にさらに注意を払う必要があります。
背景
現象 1 - PHP のカプセル化された http リクエスト インターフェイスが URL
1 を呼び出します。応答の rawheader 値に 400 エラーが表示されます
HTTP/1.1 400 Unknown VersionServer: Tengine/2.0.3Date: Tue, 19 Jul 2016 07:38:15 GMTContent-Length: 0Connection: keep-alive
2。 3.Request .phpにカプセル化されたRequestオブジェクトのsendメソッド
nategood/httpfulのRequest::sendメソッドは、PHPのcurl_execインターフェースを使用してhttpリクエストを開始します。
/** * 发送httpful get请求 * @param [array] $params [description] * @return [object] [description] */public function sendGetRequest($serverUrl,$params){ try{ $str_params = ''; foreach ($params as $key => $value) { $str_params .= "&$key=".$value; } $response = \Httpful\Request::get($serverUrl.$str_params)->send(); return $response->body; }catch(Execption $e){ return array("statuscode"=>'-1',"message"=>'服务器出错了'); } }
4.curl_execが呼び出される前のURL値
/** * Actually send off the request, and parse the response * @return string|associative array of parsed results * @throws ConnectionErrorException when unable to parse or communicate w server */public function send(){ if (!$this->hasBeenInitialized()) $this->_curlPrep(); $result = curl_exec($this->_ch); if ($result === false) { if ($curlErrorNumber = curl_errno($this->_ch)) { $curlErrorString = curl_error($this->_ch); $this->_error($curlErrorString); throw new ConnectionErrorException('Unable to connect: ' . $curlErrorNumber . ' ' . $curlErrorString); } $this->_error('Unable to connect.'); throw new ConnectionErrorException('Unable to connect.'); } $info = curl_getinfo($this->_ch); // Remove the "HTTP/1.x 200 Connection established" string and any other headers added by proxy $proxy_regex = "/HTTP\/1\.[01] 200 Connection established.*?\r\n\r\n/s"; if ($this->hasProxy() && preg_match($proxy_regex, $result)) { $result = preg_replace($proxy_regex, '', $result); } $response = explode("\r\n\r\n", $result, 2 + $info['redirect_count']); $body = array_pop($response); $headers = array_pop($response); curl_close($this->_ch); return new Response($body, $headers, $this, $info); }
現象2 - ブラウザでURLに直接アクセス
http://192.168.59.146/api?version=1.0&format=json&appkey=KtSNKxk3&access_token=changyanyun&method=pan.file.export&uid=3062000039000412278&fileId=3aaaa5c8-3eaa-4511-91e7-46831d418f10&fileIndex={"lifecycle":{"auditstatus":"0"},"general":{"source":"UGC","creator":"\u6559\u5e080523","uploader":"gsres_iflytek_f968bca78360d38abcbaf23a5a318b12","extension":"ppt","title":"Unit12 What did you do last weekdend\u8bfe\u65f64\uff081\uff09"},"properties":{"subject":["01"],"edition":["01"],"stage":["010001"],"book":["01010101-001"],"unit":["01"],"course":[""],"unit1":["01"],"unit2":[""],"unit3":[""],"phase":["03"],"type":["0100"],"rrtlevel1":["08"]}}
現象1と現象2のURL値を比較すると、 find:
fileIndexパラメータ値はjson文字列です
現象2では、fileIndexパラメータ値のtitle属性値の空白文字は%20としてエンコードされ、二重引用符「」は%22としてエンコードされます。はブラウザによって自動的に実行されます
URL を置き換えます 内のスペースがエンコードされた後、curl_exec インターフェイスは 200 を返します
テスト コード
http://192.168.59.146/api?version=1.0&format=json&appkey=KtSNKxk3&access_token=changyanyun&method=pan.file.export&uid=3062000039000412278&fileId=3aaaa5c8-3eaa-4511-91e7-46831d418f10&fileIndex={ %22lifecycle%22:{ %22auditstatus%22:%220%22},%22general%22:{ %22source%22:%22UGC%22,%22creator%22:%22\u6559\u5e080523%22,%22uploader%22:%22gsres_iflytek_f968bca78360d38abcbaf23a5a318b12%22,%22extension%22:%22ppt%22,%22title%22:%22Unit12%20What%20did%20you%20do%20last%20weekdend\u8bfe\u65f64\uff081\uff09%22},%22properties%22:{ %22subject%22:[%2201%22],%22edition%22:[%2201%22],%22stage%22:[%22010001%22],%22book%22:[%2201010101-001%22],%22unit%22:[%2202%22],%22course%22:[%22%22],%22unit1%22:[%2202%22],%22unit2%22:[%22%22],%22unit3%22:[%22%22],%22phase%22:[%2203%22],%22type%22:[%220100%22],%22rrtlevel1%22:[%2208%22]}}
パーセント エンコード (つまり、URL エンコード)
一般的に言えば、URL では英語の文字とアラビア語のみを使用できます数字と特定の句読点は使用できません。その他の単語と記号は、ネットワーク標準 RFC 1738 に必須の規定があると Ruan Yifeng 氏のブログ投稿で述べられています:
"...英数字 [0-9a-zA-Z] のみ。 、特殊文字「$-.+ !*'()」[引用符は含まない]、および予約された目的で使用される予約文字は、URL 内でエンコードせずに使用できます。"
"文字と数字のみ [0 -9a-zA-Z]、一部の特殊記号「$-.+!*'()」[二重引用符を除く]、および特定の予約語は、エンコードせずに URL 内で直接使用できます。 「
url エンコーディングは、特定のコンテキストにおける URL (Uniform Resource Locator) のエンコーディング メカニズムです。サーバーが http リクエストを解析するときに非標準文字に遭遇した場合、非標準文字をエンコードします
概要
いつ」 http リクエストに 400 が表示される エラーが発生する場合は、通常、無効な http リクエスト (不正なリクエスト) と URL パラメータのエンコード形式が間違っていることが原因です。一般に、URL には特定の形式要件があります。スペースや二重文字などの他の文字も使用できます。ただし、ブラウザで直接アクセスする場合は、引用符をエンコードする必要があります。たとえば、curl_exec を使用して PHP を呼び出す場合、スペースなどの不正な文字がエンコードされます
、特に URL パラメーターに JSON データ値が含まれる場合は、URL がエンコードされます。