Retorno de chamada JSONP não é executado ao executar em localhost
Isso é bizarro, eu estava me perguntando se alguém poderia lançar alguma luz sobre por que isso aconteceu.
Basicamente, tenho puxado meu cabelo tentando testar JSONP para poder implementar um serviço web JSON que outros sites possam usar. Estou desenvolvendo o localhost - especificamente, o Visual Studio 2008 e o servidor web integrado do Visual Studio 2008.
Então, como um teste JSONP executado com jQuery, eu implementei o seguinte:
$().ready(function() {
debugger;
try {
$.getJSON("<%= new Uri(Request.Url, "/").ToString() %>XssTest?callback=?", function(data) {
alert(data.abc);
});
} catch (err) {
alert(err);
}
});
E no servidor ..
<%= Request["callback"] %>({abc : 'def'})
Então, o que acaba acontecendo é definir um ponto de interrupção no servidor e recebo o ponto de interrupção no primeiro "depurador"; statment no script do lado do cliente, bem como no servidor. A URL JSONP está realmente sendo chamada depois que a página é carregada. Isso está funcionando muito bem.
O problema que eu estava tendo era que o retorno de chamada nunca seria executado. Eu testei isso tanto no IE8 quanto no Firefox 3.5. Nenhum deles invocaria o retorno de chamada. A captura (err) nunca foi alcançada. Nada aconteceu em tudo!
Eu fiquei preso nisso por uma semana, e até testei com uma solicitação HTTP com chave manualmente em Telnet na porta especificada para ter certeza de que o servidor está retornando o formato ...
callbackfn({abc : 'def'})
.. e isso é.
Então, ocorreu-me, e se eu mudar o nome do host de localhost para localhost com um globalizer ('.'), Ou sejahttp://localhost.:41559/ ao invés dehttp: // localhost: 41559 / (sim, adicionar um ponto a qualquer nome de host é legal, é para o DNSglobal::
é para namespaces C #). E então funcionou! O Internet Explorer e o Firefox 3.5 finalmente me mostraram uma mensagem de alerta quando eu adicionei um ponto.
Então isso me faz pensar, o que está acontecendo aqui? Por que a geração tardia de tags de script funcionaria com um nome de host da Internet e não com o host local simples? Ou essa é a pergunta certa?
Claramente isso é implementado por razões de segurança, mas o que eles estão tentando proteger? E, ao fazê-lo funcionar com um ponto, acabei de expor uma falha de segurança nesse recurso de segurança?
By the way, meu arquivo de hosts, embora alterado para outros hosts, não tem nada de especial acontecendo com localhost; o padrão 127.0.0.1 / :: 1 ainda está em vigor, sem substituições abaixo.
ACOMPANHAMENTO: Passei por isso para fins de desenvolvimento local, adicionando:
127.0.0.1 local.mysite.com
.. ao meu arquivo de hosts, adicionando o seguinte código ao meu global.asax:
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (Request.Headers["Host"].Split(':')[0] == "localhost")
{
Response.Redirect(
Request.Url.Scheme
+ "://"
+ "local.mysite.com"
+ ":" + Request.Url.Port.ToString()
+ Request.Url.PathAndQuery
, true);
}
}