Não podemos implementar o protocolo HTTP usando apenas um corpo de solicitação e um corpo de resposta?
Por exemplo, a URL conterá uma solicitação, que será mapeada para uma função dependendo da linguagem de programação no lado do servidor, por exemplo, um Servlet e, em resposta, a resposta HTML e JavaScript será enviada.
Por que o protocolo HTTP tem noção de métodos?
A partir das respostas, entendo por que o conceito de métodos existe ... Isso leva a outra pergunta relacionada:
Por exemplo, no link de composição do gmail, a solicitação e os dados PUT / POST serão enviados. Como o navegador descobre qual método usar? A página do gmail enviada pelo servidor inclui o nome do método a ser usado ao chamar a solicitação de composição do gmail? quando chamamos www.gmail.com, ele deve estar usando o método GET, como o navegador sabe que esse método deve ser usado?
PS : Não tenho créditos suficientes para comentar as respostas, por isso não consigo comentar muitas perguntas levantadas por pessoas relacionadas à intenção por trás dessa pergunta.
Como algumas respostas dizem, podemos criar novos usuários no método DELETE, e isso levanta a questão por trás da noção de métodos no protocolo http, porque no final do dia, depende totalmente dos servidores para que função eles desejam mapear uma URL. . Por que o cliente deve informar aos servidores quais métodos usar para um URL.
fonte
Respostas:
Observe que a pergunta foi alterada / esclarecida desde que a resposta foi escrita pela primeira vez. Uma resposta adicional à iteração mais recente da pergunta é após a segunda regra horizontal
Eles, juntamente com algumas outras coisas, como formatos de cabeçalho, regras de como os cabeçalhos e os corpos são separados, formam a base do protocolo HTTP
Não, porque o que você criou não seria o protocolo HTTP
Parabéns, você acabou de inventar um novo protocolo! Agora, se você deseja configurar um corpo de padrões para guiá-lo e mantê-lo, desenvolvê-lo etc., ele pode ultrapassar o HTTP um dia
Aprecio que isso seja um pouco irritante, mas não há nada mágico na Internet, TCP / IP ou na comunicação que ocorre entre servidores e clientes. Você abre uma conexão e envia algumas palavras pelo fio, formando uma conversa. A conversa realmente precisa aderir a algumas especificações ratificadas nos dois extremos para que as solicitações sejam entendidas e que respostas sensatas sejam entregues. Isso não é diferente de nenhum diálogo no mundo. Você fala inglês, seu vizinho fala chinês. Espero que sua mão acenando, apontando e apertando o punho seja suficiente para transmitir sua mensagem de que você não quer que ele estacione o carro na frente de sua casa.
De volta à Internet, se você abrir um soquete para um servidor Web compatível com HTTP e enviar o seguinte:
(O início de uma transmissão de email SMTP), você não receberá uma resposta sensata. Você pode criar o cliente compatível com SMTP mais perfeito, mas seu servidor da Web não fala com ele, porque esta conversa é sobre o protocolo compartilhado - sem protocolo compartilhado, sem alegria.
É por isso que você não pode implementar o protocolo HTTP sem implementar o protocolo HTTP; se o que você escreve não está em conformidade com o protocolo, simplesmente não é o protocolo - é outra coisa e não funcionará conforme especificado no protocolo
Se corrermos com o seu exemplo por um momento; onde o cliente se conecta e apenas declara algo que se parece com uma URL. E o servidor entende e envia apenas algo que se parece com HTML / JS (uma página da Web) e, com certeza, pode funcionar. O que você salvou? Alguns bytes em não dizer GET? Poucos mais para abandonar esses cabeçalhos desagradáveis. O servidor também salvou alguns - mas e se você não conseguir descobrir o que ele enviou? E se você solicitasse um URL que terminasse em JPEG e enviasse alguns bytes para criar uma imagem, mas esteja em PNG? Um PNG incompleto. Se ao menos tivéssemos um cabeçalho que dissesse quantos bytes estavam indopara enviar, saberíamos se o número de bytes que recebemos era realmente o arquivo inteiro ou não. E se o servidor compactasse a resposta com zíper para economizar largura de banda, mas não lhe dissesse? Você gastará um considerável poder computacional tentando descobrir o que foi enviado.
No final do dia, precisamos de metainformação - informações sobre informações; precisamos de cabeçalhos; precisamos que os arquivos tenham nomes, extensões, datas criadas. Precisamos que as pessoas tenham aniversários, para agradecer e agradecer, etc. - o mundo está cheio de protocolos e informações sobre o contexto, para que não tenhamos que sentar e resolver tudo do zero o tempo todo. Custa um pouco de espaço de armazenamento, mas vale a pena facilmente
Indiscutivelmente, não é necessário implementar todo o protocolo especificado, e isso geralmente é verdade para qualquer coisa. Eu não conheço todas as palavras no idioma inglês; meu vizinho chinês também é desenvolvedor de software, mas em um setor diferente e ele não conhece nem o chinês para alguns dos termos usados no meu setor, muito menos o inglês. O bom é que, nós dois podemos pegar um documento sobre a implementação do HTTP, ele pode escrever o servidor e eu posso escrever o cliente, em diferentes linguagens de programação em diferentes arquiteturas, e eles ainda funcionam porque aderem ao protocolo
Pode ser que nenhum de seus usuários emita algo que não seja uma solicitação GET, não use conexões persistentes, envie algo que não seja JSON como o corpo ou precise aceitar algo que não seja texto / simples para que você possa escreva um servidor Web realmente reduzido que atenda apenas às demandas muito limitadas do navegador do cliente. Mas você não pode simplesmente decidir arbitrariamente acabar com as regras básicas que tornam "algum texto passando por um soquete" o que é HTTP; você não pode abandonar a noção básica de que a solicitação será uma string como:
E a resposta terá uma versão, código de status e talvez cabeçalhos. Se você mudar alguma coisa - não é mais HTTP - é outra coisa e só funcionará com algo projetado para entendê-la. HTTP é o que essas definições definem; portanto, se você deseja implementá-lo, deve seguir as definições
Atualizar
Sua pergunta evoluiu um pouco, aqui está uma resposta para o que você pergunta:
Historicamente, você precisa entender que as coisas eram muito mais inflexíveis em seu design e implementação, mesmo na extensão em que o script não existia e até na noção de que as páginas poderiam ser dinâmicas, geradas instantaneamente na memória e pressionadas no soquete. de ser um arquivo estático no disco solicitado pelo cliente e lido e pressionado o soquete, não existia. Como a Web muito antiga se concentrava na noção de páginas estáticas que continham links para outras páginas, todas as páginas existentes no disco e na navegação teriam sido feitas pelo terminal, na maioria das vezes, solicitando GET para páginas em URLs, o servidor poderia mapear o URL para um arquivo no disco e envie-o. Havia também essa noção de que a teia de documentos vinculados entre si e enviados a outros lugares deveria ser uma evolução,
Isso fornece um contexto histórico para os métodos - uma vez que o URL era o bit inflexível e se referia simplisticamente às páginas em disco, de modo que o método era útil porque permitiu ao cliente descrever qual a intenção que ele tinha para o arquivo e o servidor. processe o método de alguma maneira variável. Não havia realmente a noção de que os URLs eram virtuais ou usados para alternar ou mapear na visão original de um hipertexto (e realmente era apenas texto).
Não pretendo que esta resposta seja uma documentação do registro histórico com datas e referências citadas exatamente quando as coisas começaram a mudar - para que você provavelmente possa ler a Wikipedia - mas é suficiente dizer que, com o tempo, o desejo de web para obter mais impulso e, em cada extremidade da conexão servidor-cliente, temos a oportunidade de criar uma rica experiência multimídia. Os navegadores suportaram uma enorme proliferação de tags para formatar o conteúdo, cada uma correndo para implementar recursos essenciais de riqueza de mídia e novas maneiras de fazer as coisas parecerem engraçadas.
Os scripts chegaram ao cliente e os plug-ins e as extensões do navegador, todos destinados a transformar o navegador em uma potência imensamente capaz de tudo. No final do servidor, a geração ativa de conteúdo com base em algoritmos ou dados do banco de dados foi o grande impulso e continua a se desenvolver na medida em que provavelmente existem poucos arquivos no disco - com certeza, mantemos um arquivo de imagem ou script como um arquivo. o servidor da Web e o navegador OBTÊM, mas cada vez mais as imagens que o navegador mostra e os scripts executados não são arquivos que você pode abrir no explorador de arquivos, eles geram conteúdo que é o resultado de algum processo de compilação sob demanda , SVG que descreve como desenhar pixels em vez de uma matriz de pixels de bitmap ou JavaScript emitido a partir de uma forma de script de nível superior, como o TypeScript
Ao criar páginas modernas com vários megabytes, provavelmente apenas uma fração dela agora é conteúdo fixo em um disco; os dados do banco de dados são formatados e modelados em html que o navegador consumirá e são feitos pelo servidor em resposta a várias rotinas de programação diferentes que são referenciadas de alguma forma pelo URL
Eu mencionei nos comentários à pergunta que é um pouco como um círculo completo. Quando os computadores custavam centenas de milhares e enchiam salas, era comum permitir a vários usuários usar o mainframe central super poderoso por meio de centenas de terminais burros - um teclado e mouse, uma tela verde, enviar algum texto, obter alguns texto para fora. Com o tempo, quando o poder da computação aumentou e os preços caíram, as pessoas começaram a usar computadores de mesa mais poderosos que os mainframes anteriores e a capacidade de executar aplicativos poderosos localmente, para que o modelo de mainframe se tornasse desatualizado. Porém, ele nunca foi embora, porque as coisas evoluíram para mudar de outra maneira e reverter para um servidor central, fornecendo a maior parte da funcionalidade útil do aplicativo e uma centena de computadores clientes que fazem muito pouco, exceto desenhar na tela, e envie e receba dados de / para o servidor. O período intermediário em que seu computador foi inteligente o suficiente para executar sua própria cópia de palavras e perspectivas ao mesmo tempo deu lugar novamente ao escritório on-line, onde seu navegador é um dispositivo para desenhar imagens na tela e editar o documento / e-mail para você ' reescrever como algo que mora no servidor, é salvo lá, enviado e compartilhado com outros usuários, como a noção de que o navegador é apenas um shell que fornece uma visão parcial a qualquer momento dessa coisa que mora em outro lugar
Ele usa GET por padrão, por convenção / especificação, pois é o que é decretado que acontecerá quando você digitar um URL e pressionar Enter.
Essa é uma das principais coisas a que aludo nos comentários acima. Na web moderna, não se trata mais de páginas. Uma vez que as páginas eram arquivos em disco, o navegador GET. Em seguida, eles se tornaram páginas predominantemente geradas dinamicamente, colocando os dados em um modelo. Mas ainda envolvia um processo de "solicitar uma nova página do servidor, obter uma página, mostrar página". A troca de página ficou muito boa; você não os viu carregar, redimensionar e alterar o layout, tornando-o mais suave, mas ainda assim o navegador estava substituindo uma página inteira ou parte de uma página por outra
A maneira moderna de fazer as coisas é com um aplicativo de página única; o navegador tem um documento na memória que é exibido de uma certa maneira, o script chama o thebservr e recupera algumas informações, e manipula o documento para que parte da página mude visualmente para mostrar as novas informações - tudo é executado sem o navegador sempre carregando outra nova página; tornou-se uma interface do usuário em que partes dele são atualizadas como um aplicativo cliente típico, como palavras ou perspectivas. Novos elementos aparecem em cima de outros elementos e podem ser arrastados simulando janelas de diálogo etc. Tudo isso É o mecanismo de script do navegador que envia solicitações usando o método http que o desenvolvedor deseja, recuperando dados e cutucando o documento que o navegador está desenhando. Você pode imaginar que o navegador moderno é um dispositivo brilhante que é algo como um sistema operacional inteiro ou um computador virtual; um dispositivo programável que possui uma maneira bastante padronizada de desenhar coisas na tela, reproduzir som, capturar a entrada do usuário e enviá-la para processamento. Tudo o que você precisa fazer para desenhar sua interface do usuário é fornecê-lo com alguns html / css que fazem com que a interface do usuário ajuste o html constantemente para fazer com que o navegador altere o que está desenhando. Caramba, as pessoas estão tão acostumadas a ver a barra de endereço alterada / usando-a como uma direção de intenção que um aplicativo de página única altera a URL programaticamente, mesmo que nenhuma navegação (solicitando novas páginas inteiras) esteja sendo feita Tudo o que você precisa fazer para desenhar sua interface do usuário é fornecê-lo com alguns html / css que fazem com que a interface do usuário ajuste o html constantemente para fazer com que o navegador altere o que está desenhando. Caramba, as pessoas estão tão acostumadas a ver a barra de endereço alterada / usando-a como uma direção de intenção que um aplicativo de página única altera a URL programaticamente, mesmo que nenhuma navegação (solicitando novas páginas inteiras) esteja sendo feita Tudo o que você precisa fazer para desenhar sua interface do usuário é fornecê-lo com alguns html / css que fazem com que a interface do usuário ajuste o html constantemente para fazer com que o navegador altere o que está desenhando. Caramba, as pessoas estão tão acostumadas a ver a barra de endereço alterada / usando-a como uma direção de intenção que um aplicativo de página única altera a URL programaticamente, mesmo que nenhuma navegação (solicitando novas páginas inteiras) esteja sendo feita
Verdade. Porque está especificado. A primeira solicitação é como historicamente sempre foi: obtenha um html inicial para desenhar uma interface do usuário, então cutuque e manipule-a para sempre ou obtenha outra página com outro script que cutuca e manipula e cria uma interface de usuário reativa responsiva
História. Legado. Teoricamente, poderíamos lançar todos os métodos http amanhã - estamos em um nível de sofisticação de programação em que os métodos são obsoletos porque os URLs são processáveis na medida em que podem ser o mecanismo de alternância que indica ao servidor em que você deseja salvar os dados. o corpo como um rascunho de email ou exclua um rascunho - não há um arquivo / emails / draft / save / 1234 no servidor - o servidor está programado para separar esse URL e saber o que fazer com o corpo - salvar como um rascunho de email sob o ID 1234
Portanto, é certamente possível acabar com os métodos, exceto pelo enorme peso da compatibilidade herdada que cresceu à sua volta. É melhor apenas usá-los para o que você precisa, mas ignorá-los amplamente e, em vez disso, use o que for necessário para que suas coisas funcionem. Ainda precisamos de métodos como especificado, porque é preciso lembrar que eles significam algo para o navegador e o servidor, além dos quais criamos nossos aplicativos. O script do lado do cliente deseja usar o navegador subjacente para enviar dados; ele precisa usar um método que faça com que o navegador faça o que pede - provavelmente um POST, porque o GET empacota todas as informações variáveis no URL e tem um limite de comprimento em muitos servidores. O cliente deseja uma resposta longa do servidor - não use um HEAD, porque eles não deveriam ter corpos de resposta.
fonte
O HTTP pode ser considerado como um caso específico de princípios genéricos da Chamada de Procedimento Remoto: você diz ao servidor o que deseja com algum campo variável da solicitação, o servidor responde de acordo. Até agora, devido à complexa interatividade da 'Web 2.0', esses mesmos recursos são empurrados em todos os campos da solicitação: a URL, os cabeçalhos, o corpo - e cada servidor de aplicativos e aplicativo os entende da sua maneira. No entanto, originalmente a web era mais simples, usava páginas estáticas e pensava-se que os métodos HTTP forneciam o nível de interatividade suficiente. Notavelmente, o HTTP tem muitos métodos usados raramente, se é que alguma vez, com alguns deles apenas vendo a luz graças ao REST. Por exemplo, PUT e DELETE eram moribundos antes do REST, e TRACE e PATCH ainda não foram vistos. O argumento é que o modelo de RPC do HTTP não
O REST fez exatamente o oposto do que você está propondo, observando que os métodos HTTP atendem aos casos de uso CRUD típicos da maioria dos aplicativos se PUT e DELETE forem trazidos de volta.
Observe também que os métodos HTTP têm semântica atribuída a eles, que são respeitados por navegadores e middleware como servidores proxy: solicitações POST, PUT, DELETE e PATCH podem ter efeitos colaterais e provavelmente não serem idempotentes, portanto, aplicativos e middleware do lado do cliente devem ter cuidado para não acionar essas solicitações sem ação expressa do usuário. Na prática, aplicativos da Web mal projetados usavam GET para ações não seguras e, por exemplo, o pré-buscador do Google Web Accelerator causou problemas ao excluir um monte de dados nesses sites , então sua versão beta foi suspensa logo após o lançamento.
Portanto, para responder à pergunta 'podemos': com certeza, você só precisa concordar com um protocolo que informe ao aplicativo do servidor qual ação você deseja executar e, em seguida, coloque os argumentos em algum lugar do URL / corpo - como o item de destino para a ação. O conjunto de ações é limitado apenas por aplicativos específicos, portanto, você precisa de um protocolo extensível. Mas você precisará informar aos aplicativos clientes quais solicitações são seguras e provavelmente levar em consideração outras nuances, como controle de cache.
fonte
Do meu ponto de vista pessoal como desenvolvedor, isso pode facilitar muito a criação de terminais da API. Por exemplo, se eu escrever um controlador que gerencia produtos em um site, posso usar o mesmo URL para realizar várias operações diferentes.
Exemplos:
Isso buscará os detalhes do produto 1234.
Isso criará um produto com o ID 1234 usando dados no corpo da solicitação.
Isso atualizará o produto 1234 com dados no corpo da solicitação.
Isso excluirá um produto com o ID 1234.
Eu poderia criar pontos de extremidade diferentes para cada operação, mas isso complicaria o processo e o tornaria menos compreensível para outros desenvolvedores.
fonte
Parece que você esqueceu os velhos tempos em que os servidores HTTP estavam lá apenas para servir arquivos ; não executando script, CGI ou criando conteúdo dinâmico desse tipo.
Os métodos de solicitação são um conjunto padronizado básico de verbos sobre o que fazer com esses arquivos ...
No dia do HTTP / 0.9, a linha de solicitação é a única coisa na seção de solicitação do protocolo; sem cabeçalhos de solicitação, sem cabeçalhos de resposta. Basta digitar
GET /somefile
, pressionar Enter, o servidor retornará o corpo da resposta (ou seja, conteúdo HTML) e tudo bem, obrigado, tchau (ou seja, feche a conexão).Se você quis apenas perguntar por que foi projetado dessa maneira ? Minha resposta é porque ele foi originalmente escrito para lidar com o tipo de troca de conteúdo existente na época , ou seja, a veiculação de arquivos HTML estáticos a pedido dos usuários.
No entanto, se você quis perguntar sobre como tratar essas semânticas no servidor de aplicativos moderno ...
Minha resposta é: faça o que você gostaria de fazer, mas lembre-se de que você não deve implementar a lógica do aplicativo de uma maneira que desafie as expectativas do protocolo : expectativas como GET não devem alterar dados (ou muito vagamente, ter pelo menos resultados idempotentes) ), HEAD deve ter o mesmo resultado que GET, mas sem o corpo da resposta, PUT deve disponibilizar o conteúdo do URI de destino (se for bem-sucedido).
Se você for contra as expectativas sem considerar cuidadosamente suas implicações , várias coisas desagradáveis aconteceriam, como ...
wget --spider
) são liberadas no seu site." Iniciantes conhecem regras, mas veteranos conhecem exceções. "
De qualquer forma, você pode encontrar algumas desculpas válidas para contrariar algumas das regras de alguns casos de uso restritos; mas faça sua pesquisa e considere todas as possibilidades. Caso contrário, você acabará prejudicando a interoperabilidade e arruinando as "experiências do usuário".
Não há garantia de que os usuários sempre usem a distribuição mais recente e brilhante dos principais clientes / agentes de marca que você testou. Eles podem usar uma marca local adaptada às suas necessidades (inclusive eu), uma personalizada que encomendaram em uma loja especializada ao lado ou uma vintage que cavaram em uma despensa. Mesmo com tudo isso, espera-se que seus sites ofereçam um serviço razoável. Essa é uma razão pela qual temos padrões.
Quebrar descuidadamente o padrão também significa que você está aplicando discriminação aos seus usuários.
fonte
É verdade que, em teoria, poderíamos usar todos os lugares e isso funcionaria. Alguns softwares até usam GET com o corpo da solicitação (eu estou olhando para você elasticsearch / kibana). É claro que isso é uma coisa horrível.
A razão mais importante é porque os diferentes métodos têm semântica diferente. Alguns são seguros, outros são idempotentes. Alguns são ambos. Veja quais são quais
Isso é importante, por exemplo, ao interagir com outros aplicativos. Os pontos de extremidade GET não devem ter efeitos colaterais. Isso é importante quando o Google está rastreando seu lado. PUT deve ser idempotente, o que significa que o cliente está livre para tentar novamente em caso de falha. Não é o caso do POST, motivo pelo qual os navegadores precisam ter uma caixa de confirmação feia se você pressionar f5 em uma solicitação de postagem.
Veja o que pode acontecer se você usar GET, onde deveria ter usado o POST
fonte
Você também pode pensar em GET, POST etc. como sobrecargas da mesma função, ou mesmo como getters e setters.
GET_MyVar()
não aceita um parâmetro de entrada (também conhecido como corpo da solicitação), mas retorna algo.POST_MyVar(string blah)
faz algo com a entrada (novamente, o corpo da solicitação) e pode retornar algo. (Também precisa pelo menos retornar um código de resposta, para que saibamos que a função foi executada !!)DELETE_MyVar()
Provavelmente também não leva nada e espera-se excluir alguma coisa.Sim, podemos implementar tudo com:
MyVar(string Action, string? blah)
Dessa forma, poderíamos aceitar apenas uma chamada e depois escolher o que fazer com base em algum outro parâmetro.
Mas uma das conveniências dessa abordagem é que ela permite que navegadores e servidores otimizem a maneira como essas coisas funcionam. Por exemplo, talvez o servidor queira bloquear todas as solicitações onde
Action==DELETE
. Talvez os navegadores desejem armazenar em cache coisas em que,Action==GET.
caso contrário, em todas as funções teríamos que escreverif (Action==Delete) {return AngryFace}
Não há requisitos para implementar tudo exatamente de acordo com o protocolo, mas o protocolo é basicamente um conjunto de regras que todos decidimos seguir. Dessa forma, posso adivinhar facilmente o que seu site fará, mesmo que eu não tenha visto o servidor!
fonte
Os métodos HTTP servem a propósitos diferentes. Em geral,
GET
é para downloads ePOST
é para uploads.A única maneira de implementar parte do protocolo HTTP usando apenas um corpo de solicitação e um corpo de resposta seria implementar
POST
.GET
não possui um corpo de solicitação. Ele só possui a solicitação com cabeçalhos, mas sem corpo. É apenas uma solicitação de download de um documento.POST
possui o corpo da solicitação (o upload do arquivo) e um corpo de resposta (o documento que mostra o resultado).Então você poderia simplesmente implementar
POST
e terminar? Não, se você deseja que seu site seja utilizável em navegadores padrão. O tipo de solicitação padrão que os navegadores enviam éGET
.POST
as solicitações geralmente são enviadas apenas quando formulários em páginas da web são enviados ou para chamadas AJAX. Somente se esse servidor específico estiver sendo usado apenas para chamadas AJAX, e não para páginas visíveis para os usuários, você poderá se safarPOST
apenas.Às vezes, os navegadores também enviam
HEAD
solicitações para verificar se um documento foi alterado desde a última vez em que foram baixados, por isso seria aconselhável implementá-lo também.De qualquer forma, não há um bom motivo para implementar um servidor Web para o seu site a partir do zero. O protocolo HTTP é complicado. Além dos vários métodos, você também teria que implementar solicitações de pipelining e chunked. É muito mais fácil criar seu aplicativo da Web sobre um servidor da Web como Apache, Nginx ou IIS que lida com o protocolo HTTP para você. Você menciona Servlets, portanto, talvez você deva usar servidores Web Tomcat ou JBoss que executam Servlets.
fonte
Você está correto, poderíamos fazer exatamente isso, GET, POST, PUT etc. são apenas convenções históricas, se eu tivesse o meu caminho, o HTTP seria substituído com apenas o método POST e nada mais, embora eu tenha que admitir que eliminar o GET seria uma tarefa enorme, isso não podia ser feito, o cavalo já trancou naquele
fonte
Seu protocolo proposto seria significativamente menos seguro contra hackers.
Há uma razão pela qual os sites deixaram de armazenar informações sobre variáveis e outras no URL, e essa razão é simples: oferece aos atacantes uma maneira muito simples de atacar seu sistema. Observando as informações da URL em texto sem formatação, elas podem determinar a forma como os dados enviados ao seu servidor da Web são construídos; eles podem usar essas informações para executar um ataque ao seu servidor usando um URL especialmente construído que lhes permite injetar código ou dados maliciosos no seu servidor.
fonte