php-Android上的idHTTP无法接受错误406
作者:互联网
我正在尝试使用idHTTP和PHP脚本在MySQL数据库上发布插入内容.这是要插入数据库的PHP脚本:
$mysqli = new mysqli($servidor, $usuario, $senha, $banco);
// Caso algo tenha dado errado, exibe uma mensagem de erro
if (mysqli_connect_errno()) trigger_error(mysqli_connect_error());
$iduser = quoted_printable_decode($_POST['iduser']);
$nome = quoted_printable_decode($_POST['nome']);
$data = quoted_printable_decode($_POST['data']);
$hora = quoted_printable_decode($_POST['hora']);
$mensagem = quoted_printable_decode($_POST['mensagem']);
$latitude = quoted_printable_decode($_POST['latitude']);
$longitude = quoted_printable_decode($_POST['longitude']);
$imagem = $_FILES["imagem"]['tmp_name'];
$tamanho = $_FILES['imagem']['size'];
header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
header('Content-Type: text/plain; charset="utf-8"');
if ( $imagem != "none" )
{
$fp = fopen($imagem, "rb");
$conteudo = fread($fp, $tamanho);
$conteudo = addslashes($conteudo);
fclose($fp);
$queryInsercao = "INSERT INTO tabpainel (iduser, nome, data, hora, mensagem, latitude, longitude, imagem) VALUES ('$iduser', '$nome', '$data','$hora','$mensagem', '$latitude', '$longitude', '$conteudo')";
mysqli_query($mysqli,$queryInsercao) or die("Algo deu errado ao inserir o registro. Tente novamente.");
if (mysqli_affected_rows($mysqli) > 0)
include 'baixarpainel.php';
else
print utf8_encode("Não foi possível inserir o registro");
}
else
print utf8_encode("Não foi possível carregar a imagem.");
?>
在Delphi中,我使用的是:
FormPHP := TIdMultiPartFormDataStream.Create;
FormPHP.AddFile ('imagem', AImagem, 'image/jpeg');
FormPHP.AddFormField ('iduser', AIDUser, 'utf-8');
FormPHP.AddFormField ('nome', ANome, 'utf-8');
FormPHP.AddFormField ('data', AData, 'utf-8');
FormPHP.AddFormField ('hora', AHora, 'utf-8');
FormPHP.AddFormField ('mensagem', AMensagem, 'utf-8');
FormPHP.AddFormField ('latitude', '1');
FormPHP.AddFormField ('longitude', '1');
Response := TStringStream.Create('',TEncoding.UTF8);
HTTP:= TIdHTTP.Create(self);
HTTP.Post('http://addressexample.com/cadastro.php',FormPHP,Response);
在必须更换托管公司之前,它一直工作良好.使用Hostinger可以,但使用Hostgator则不行.使用Hostgator,idHTTP会在类EIdHTTPProtocalException中引发异常,并显示消息:“ HTTP / 1.1 406 Not Acceptable”. Hostgator支持已禁用mod_security,这可能会导致问题.
仅在Android上发生此异常.在Windows上使用相同的应用程序,效果很好.
更新:我尝试了另一件事. PHP脚本是这样的:
// Conecta-se ao banco de dados MySQL
$mysqli = new mysqli($servidor, $usuario, $senha, $banco);
// Caso algo tenha dado errado, exibe uma mensagem de erro
if (mysqli_connect_errno()) trigger_error(mysqli_connect_error());
# Instanciando o XMLWriter
$xml = new XMLWriter;
$xml->openMemory();
# Definindo o encoding do XML
$xml->startDocument( '1.0', 'UTF-8');
# Primeiro elemento do XML
$xml->startElement("DATAPACKET");
$xml->writeAttribute("version", "2.0");
$xml->StartElement("METADATA");
$xml->startElement("FIELDS");
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "id");
$xml->writeAttribute("fieldtype", "I4");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "iduser");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "30");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "nome");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "200");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "data");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "8");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "hora");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "5");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "mensagem");
$xml->writeAttribute("fieldtype", "String");
$xml->writeAttribute("Width", "3000");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "latitude");
$xml->writeAttribute("fieldtype", "r8");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "longitude");
$xml->writeAttribute("fieldtype", "r8");
$xml->endElement();
$xml->startElement("FIELD");
$xml->writeAttribute("attrname", "imagem");
$xml->writeAttribute("fieldtype", "bin.hex");
$xml->writeAttribute("subtype", "Binary");
$xml->endElement();
$xml->endElement(); //FIELDS
$xml->endElement(); //METADATA
$xml->StartElement("ROWDATA");
# Query na tabela escolhida
$rs_table = $mysqli->query("select * from tabpainel ORDER BY id DESC LIMIT 50");
while($table = $rs_table->fetch_array(MYSQLI_ASSOC))
{
# Transformando array em objeto
$table = (object)$table;
# Criando elemento tabela
$xml->StartElement("ROW");
# Setando os atributos
$xml->writeAttribute("id", "$table->id");
$xml->writeAttribute("iduser", "$table->iduser");
$xml->writeAttribute("nome", "$table->nome");
$xml->writeAttribute("data", "$table->data");
$xml->writeAttribute("hora", "$table->hora");
$xml->writeAttribute("mensagem", "$table->mensagem");
$xml->writeAttribute("latitude", "$table->latitude");
$xml->writeAttribute("longitude","$table->longitude");
$xml->writeAttribute("imagem", base64_encode("$table->imagem"));
$xml->endElement();
}
# Fechando o ROWDATA
$xml->endElement();
# Fechando o elemento DATAPACKET
$xml->endElement();
# Encerrando a conexao
//$con->close();
# Definindo cabecalho de saida
header("content-type: application/xml; charset=utf-8");
# Imprimindo a saida do XML
print $xml->outputMemory(true);
?>
而且我使用了http.get来接收xml:
Http.HandleRedirects:= true;
Http.request.useragent := 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; MAAU)';
MS.Text:= Http.get('http://addressexample.com/baixarpainel.php');
MS.SaveToFile(FarquivoBaixado);
这在Android上也很好用.问题仍然仅在Android上为http.post.
解决方法:
由于Indy使用单个跨平台代码库,因此TIdHTTP在所有平台上的工作方式都完全相同.因此,生成的HTTP请求在所有平台上都应该完全相同.
当HTTP请求包含没有指定服务器能够在其中呈现响应的任何媒体类型的Accept标头时,就会发生HTTP 406错误.每RFC 2616 Section 14.1:
If no Accept header field is present, then it is assumed that the client accepts all media types. If an Accept header field is present, and if the server cannot send a response which is acceptable according to the combined Accept field value, then the server SHOULD send a 406 (not acceptable) response.
您的PHP脚本正在发送文本/纯文本响应,因此,如果您发送不允许文本/纯文本的Accept标头,则可能导致406错误.听起来,Hostgator的强制执行力度要比Hostinger更大.
默认情况下,TIdHTTP将其Request.Accept属性设置为以下字符串值:
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
从技术上讲,它允许通过* / *的所有媒体类型,但是其优先级低于某些其他媒体类型.但是,如果服务器正确实现了“接受”处理,则该默认值仍应足以允许文本/纯文本响应.
您需要联系Hostgator并与他们讨论问题,因为问题出在他们的身上,而不是您的.
话虽如此,由于您知道服务器响应始终是文本/纯文本,因此可以在调用Post()之前将以下内容添加到代码中:
HTTP.Request.Accept := 'text/plain';
HTTP.Request.AcceptCharset := 'utf-8';
标签:indy,idhttp,php,android,delphi 来源: https://codeday.me/bug/20191112/2023938.html