codificação de caracteres json - o utf-8 é bem suportado por navegadores ou devo usar seqüências de escape numéricas?
<p>eu estou escrevendo um webservice que usa json para representar seus recursos, e estou um pouco preso pensando na melhor maneira de codificar o json. lendo o json rfc ( <a href="http://www.ietf.org/rfc/rfc4627.txt">http://www.ietf.org/rfc/rfc4627.txt</a> ) está claro que a codificação preferida é utf-8. mas o rfc também descreve um mecanismo de escape de string para especificar caracteres. eu suponho que isso geralmente seria usado para escapar de caracteres não ascii, tornando assim o asci utf-8 válido.</p><p>então, digamos que eu tenha uma string json que contenha caracteres unicode (code-points) que não sejam ascii. o meu webservice deve apenas utf-8 codificá-lo e devolvê-lo, ou ele deveria escapar de todos os caracteres não ascii e retornar ascii puro?</p><p>eu gostaria que os navegadores pudessem executar os resultados usando jsonp ou eval. isso afeta a decisão? meu conhecimento do suporte javascript de vários navegadores para utf-8 está faltando.</p><p>edit: eu queria esclarecer que a minha principal preocupação sobre como codificar os resultados é realmente sobre o manuseio do navegador dos resultados. o que eu li indica que os navegadores podem ser sensíveis à codificação ao usar o jsonp em particular. eu não encontrei nenhuma informação realmente boa sobre o assunto, então vou ter que começar a fazer alguns testes para ver o que acontece. idealmente, eu gostaria apenas de escapar daqueles poucos caracteres que são necessários e apenas utf-8 codificar os resultados.</p>
<p>a especificação json <em>requer</em> suporte utf-8 por decodificadores. como resultado, todos os decodificadores json podem manipular o utf-8 tão bem quanto eles podem manipular as seqüências numéricas de escape. esse também é o caso dos intérpretes de javascript, o que significa que o jsonp também lidará com o json codificado em utf-8.</p><p>a capacidade dos codificadores json de usar as seqüências numéricas de escape apenas oferece mais opções. uma razão pela qual você pode escolher as seqüências de escape numéricas seria se um mecanismo de transporte <em>entre</em> seu codificador e o decodificador pretendido não é seguro para binário.</p><p>outro motivo pelo qual você pode querer usar sequências de escape numéricas é impedir que determinados caracteres apareçam no fluxo, como <code>&lt;</code>, <code>&amp;</code> e <code>"</code>, que podem ser interpretados como sequências html se o código json for colocado sem escapar para html ou um navegador interpretar incorretamente como html. isso pode ser uma defesa contra injeção de html ou scripts entre sites (note: alguns caracteres devem ter escape em json, incluindo <code>"</code> e <code>\</code>).</p><p>algumas estruturas, incluindo a implementação do json no php, <em>sempre</em> fazem as seqüências numéricas de escape no lado do codificador para qualquer caractere fora do ascii. isso é destinado a compatibilidade máxima com mecanismos de transporte limitados e similares. no entanto, isso não deve ser interpretado como uma indicação de que os decodificadores json têm um problema com o utf-8.</p><p>então, eu acho que você só poderia decidir qual usar assim:</p><ul> <li> <p>basta usar o utf-8, a menos que seu método de armazenamento ou transporte entre o codificador e o decodificador não seja seguro para binário.</p> </li> <li> <p>caso contrário, use as seqüências de escape numéricas.</p> </li> </ul>
<p>cria um filter e seta o encoding para utf-8, deve resolver:</p>
<pre class="prettyprint"><code>&#64;webfilter(&#34;/*&#34;)
public class characterencodingfilter implements filter {

 &#64;override
 public void dofilter(servletrequest request, servletresponse response, filterchain chain) throws servletexception, ioexception {
 request.setcharacterencoding(&#34;utf-8&#34;);
 chain.dofilter(request, response);
 }
}</code></pre> Quando o documento é transferido através de HTTP, [as informações do cabeçalho HTTP são as informações crutial](http://www.w3.org/TR/html401/charset.html#h-5.2.2) :



> 
> [...] agentes de usuário conformes devem observar as seguintes prioridades para determinar a codificação de caracteres de um documento (da mais alta prioridade para a menor):
> 
> 
> 1. Um HTTP " `charset`" parâmetro em um " `Content-Type`campo".
> 2. Uma `META`declaração com " `http-equiv`" definido para " `Content-Type`" e um valor definido para " `charset`".
> 3. O `charset`conjunto de atributos em um elemento que designa um recurso externo.
> 
> 
> 


Portanto, verifique se você declarar a codificação de caracteres no [`Content-Type`campo de cabeçalho](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17) e não apenas dentro do documento. O espaço não-separável não está sendo guardada no seu banco de dados como um personagem estrangeiro estranho, ele está sendo salvo como *dois* caracteres. O caractere de Unicode espaço sem quebra é codificado em UTF-8 como `0xC2 0xA0`, o qual na norma ISO 8859-1-se parece com "A" (isto é, um caracteres estrangeiros estranho seguido de um espaço não separável).


Você provavelmente está se esquecendo de fazer `SET NAMES 'utf8'`na sua conexão de banco de dados, o que faz com PHP para enviar seus dados para o MySQL como ISO-8859-1 (o padrão).


Dê uma olhada no " [UTF-8 todo o caminho ...](https://stackoverflow.com/questions/279170/utf-8-all-the-way-through) " para ver como configurar corretamente UTF-8 quando usando PHP e MySQL. <p>a idéia aqui é que a maioria de nós já <em> já </em> saiba <em> a maioria </em> do que está nesta lista. mas pode haver apenas um ou dois itens que você realmente não analisou antes, que não entende completamente, ou talvez nunca tenha ouvido falar.</p><p><strong> interface e experiência do usuário </strong></p><ul> <li>esteja ciente de que os navegadores implementam os padrões de maneira inconsistente e verifique se o site funciona razoavelmente bem em todos os principais navegadores. em um teste mínimo com relação a um <a href="https://en.wikipedia.org/wiki/gecko\_%28layout\_engine%29">gecko</a> engine recente ( <a href="http://firefox.com/">firefox</a> ), um mecanismo webkit ( <a href="http://www.apple.com/safari/">safari</a> e alguns navegadores móveis) , <a href="http://www.google.com/chrome">chrome</a> , seus navegadores <a href="https://en.wikipedia.org/wiki/internet\_explorer">ie suportados</a> (aproveite as <a href="http://www.microsoft.com/downloads/details.aspx?familyid=21eabb90-958f-4b64-b5f1-73d0a413c8ef&amp;displaylang=en">imagens vpc de compatibilidade de aplicativos</a> ) e <a href="http://www.opera.com/">opera</a> . considere também como <a href="http://www.browsershots.org">browsers processam seu site</a> / em diferentes sistemas operacionais.</li> <li>considere como as pessoas podem usar o site que não seja dos principais navegadores: telefones celulares, leitores de tela e mecanismos de pesquisa, por exemplo. - algumas informações de acessibilidade: <a href="http://www.w3.org/wai/"> wai </a> e <a href="http://www.section508.gov/">section508</a> , desenvolvimento móvel: <a href="http://mobiforge.com/">mobiforge</a> .</li> <li>preparo: como implantar atualizações sem afetar seus usuários. tenha um ou mais ambientes de teste ou teste disponíveis para implementar alterações na arquitetura, no código ou no conteúdo abrangente e garantir que eles possam ser implantados de maneira controlada sem quebrar nada. tenha uma maneira automatizada de implantar alterações aprovadas no site ativo. isso é implementado de maneira mais eficaz em conjunto com o uso de um sistema de controle de versão (git, subversion, etc.) e um mecanismo de compilação automatizado (ant, nant, etc.).</li> <li>não exiba erros hostis diretamente para o usuário.</li> <li>não coloque os endereços de email dos usuários em texto sem formatação, pois eles receberão spam até a morte.</li> <li>adicione o atributo \_<code>rel="nofollow"</code>\_ aos links gerados pelo usuário <a href="https://en.wikipedia.org/wiki/nofollow">para evitar spam</a> .</li> <li> <a href="http://www.codinghorror.com/blog/archives/001228.html">crie limites bem considerados no seu site</a> - isso também pertence a segurança.</li> <li>aprenda a fazer <a href="https://en.wikipedia.org/wiki/progressive\_enhancement">aprimoramento progressivo</a> .</li> <li> <a href="https://en.wikipedia.org/wiki/post/redirect/get">redirecione após um post</a> se esse post foi bem-sucedido, para impedir que uma atualização seja enviada novamente.</li> <li>não se esqueça de levar em consideração a acessibilidade. é sempre uma boa ideia e, em determinadas circunstâncias, é um <a href="http://www.section508.gov/">requisito legal</a> . <a href="http://www.w3.org/wai/intro/aria">wai-aria</a> e <a href="http://www.w3.org/tr/wcag20/">wcag 2</a> são bons recursos nessa área.</li> <li>leia <a href="http://www.sensible.com/dmmt.html">não me faça pensar</a> .</li> </ul><p><strong> segurança </strong></p><ul> <li>é muito difícil de digerir, mas o guia de desenvolvimento <a href="http://www.owasp.org/index.php/category:owasp\_guide\_project">owasp</a> cobre a segurança do site de cima para baixo.</li> <li>saiba mais sobre a injeção, especialmente <a href="https://en.wikipedia.org/wiki/sql\_injection">sql injection</a> e como evitá-la.</li> <li>nunca confie na entrada do usuário, nem em qualquer outra coisa que esteja presente na solicitação (que inclui cookies e valores ocultos do campo do formulário!).</li> <li>hash senhas usando <a href="https://security.stackexchange.com/q/21263/396">salt</a> / e use sais diferentes para suas linhas para evitar ataques do rainbow. use um algoritmo de hash lento, como bcrypt (tempo testado) ou scrypt (ainda mais forte, mas mais recente) ( <a href="http://www.tarsnap.com/scrypt.html">1</a> , <a href="http://it.slashdot.org/comments.pl?sid=1987632&amp;cid=35149842">2</a> ), para armazenar senhas. ( <a href="http://codahale.com/how-to-safely-store-a-password/">como armazenar com segurança uma senha</a> ). o <a href="https://security.stackexchange.com/q/7689/396">nist também aprova o pbkdf2 para senhas de hash</a> "e é <a href="https://security.stackexchange.com/a/2136/396">fips aprovado no .net</a> (mais informações <a href="https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords">aqui</a> ) . <em> evite </em> usar md5 ou a família sha diretamente.</li> <li> <a href="https://stackoverflow.com/questions/1581610/how-can-i-store-my-users-passwords-safely/1581919#1581919">não tente criar seu próprio sistema de autenticação sofisticado</a> . é uma coisa tão fácil cometer erros de maneiras sutis e não testáveis ​​e você nem saberia até <em> depois de </em> ser invadido.</li> <li>conheça as <a href="https://www.pcisecuritystandards.org/">regras para o processamento de cartões de crédito</a> . ( <a href="https://stackoverflow.com/questions/51094/payment-processors-what-do-i-need-to-know-if-i-want-to-accept-credit-cards-on-m">veja também esta pergunta</a> )</li> <li>use <a href="http://www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt">ssl/tls</a> / <a href="https://en.wikipedia.org/wiki/session\_hijacking#prevention"> https </a> para sites em que dados confidenciais são inseridos (como credenciais, informações de identificação pessoal, informações do cartão de crédito). <a href="https://letsencrypt.org">let's encrypt</a> é uma autoridade de certificação gratuita que pode ajudar.</li> <li> <a href="https://en.wikipedia.org/wiki/session\_hijacking#prevention">impedir o seqüestro de sessão</a> .</li> <li>evite <a href="https://en.wikipedia.org/wiki/cross-site\_scripting">scripts entre sites</a> (xss).</li> <li>evite <a href="https://en.wikipedia.org/wiki/cross-site\_request\_forgery">falsificações de solicitação entre sites</a> (csrf).</li> <li>evite <a href="https://en.wikipedia.org/wiki/clickjacking">clickjacking</a> .</li> <li>mantenha seu (s) sistema (s) atualizado (s) com as últimas correções.</li> <li>verifique se as informações de conexão do banco de dados estão protegidas.</li> <li>mantenha-se informado sobre as mais recentes técnicas de ataque e vulnerabilidades que afetam sua plataforma.</li> <li>leia <a href="https://code.google.com/archive/p/browsersec/">manual de segurança do navegador google</a> .</li> <li>leia <a href="https://rads.stackoverflow.com/amzn/click/com/0470170778">manual do hacker de aplicativos da web</a> .</li> <li>considere <a href="https://en.wikipedia.org/wiki/principle\_of\_least\_privilege">o princípio do menor privilégio</a> . tente executar o servidor de aplicativos <a href="https://security.stackexchange.com/questions/47576/do-simple-linux-servers-really-need-a-non-root-user-for-security-reasons">como não raiz</a> . ( <a href="http://tomcat.apache.org/tomcat-8.0-doc/security-howto.html#non-tomcat\_settings">exemplo do tomcat</a> )</li> <li>coloque \_<code>rel="noopener noreferrer"</code>\_ em todos os links fornecidos pelo usuário com \_<code>target="\_blank"</code>\_ para impedir que o javascript na página de destino redirecione sua página para outro lugar, como uma página de login falsa. <a href="https://dev.to/phishing">mais informações</a> </li> <li>considere usar uma <a href="https://csp.withgoogle.com/docs/index.html">política de segurança de conteúdo estrita</a> .</li> </ul><p><strong> desempenho </strong></p><ul> <li>implemente o cache, se necessário, entenda e use <a href="http://www.mnot.net/cache\_docs/">http caching</a> corretamente, bem como <a href="http://www.w3.org/tr/2011/wd-html5-20110525/offline.html">html5 manifest</a> .</li> <li>otimizar imagens - não use uma imagem de 20 kb para um fundo repetitivo.</li> <li>compactar conteúdo para velocidade, consulte <a href="https://www.smashingmagazine.com/2016/10/next-generation-server-compression-with-brotli/">brotli</a> , <a href="http://developer.yahoo.com/performance/rules.html#gzip">gzip/deflate</a> (<strike> <a href="https://stackoverflow.com/questions/1574168/gzip-vs-deflate-zlib-revisited">deflate é melhor</a> </strike>).</li> <li>combine/concatene várias folhas de estilo ou vários arquivos de script para reduzir o número de conexões do navegador e melhorar a capacidade do gzip para compactar duplicações entre arquivos.</li> <li>dê uma olhada no site <a href="http://developer.yahoo.com/performance/">yahoo exceptional performance</a> , muitas ótimas diretrizes, incluindo a melhoria do desempenho do front-end e sua <a href="http://developer.yahoo.com/yslow/">yslow</a> ferramenta (requer firefox, safari, chrome ou opera). além disso, <a href="https://developers.google.com/speed/docs/best-practices/rules\_intro">velocidade da página do google</a> (use com <a href="https://developers.google.com/speed/pagespeed/insights\_extensions">extensão do navegador</a> ) é outra ferramenta para criação de perfil de desempenho e otimiza suas imagens também.</li> <li><strike>use <a href="http://alistapart.com/articles/sprites">css image sprites</a> para imagens relacionadas pequenas, como barras de ferramentas (consulte o ponto "minimizar solicitações http")</strike></li> <li>use <a href="https://24ways.org/2014/an-overview-of-svg-sprite-creation-techniques/">sprites de imagem svg</a> para pequenas imagens relacionadas, como barras de ferramentas. a coloração svg é um pouco complicada. você pode ler sobre isso <a href="http://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css/">aqui</a> .</li> <li>sites ocupados devem considerar <a href="http://developer.yahoo.com/performance/rules.html#split">dividir componentes entre domínios</a> . especificamente...</li> <li>o conteúdo estático (ou seja, imagens, css, javascript e, geralmente, o conteúdo que não precisa de acesso a cookies) deve ir em um domínio separado <em> <a href="http://blog.stackoverflow.com/2009/08/a-few-speed-improvements/">que não usa cookies</a> </em>, porque todos os cookies de um domínio e seus subdomínios são enviados com todas as solicitações para o domínio e seus subdomínios. uma boa opção aqui é usar uma rede de entrega de conteúdo (cdn), mas considere o caso em que essa cdn pode falhar incluindo cdns alternativas ou cópias locais que podem ser veiculadas.</li> <li>minimize o número total de solicitações http necessárias para um navegador renderizar a página.</li> <li>escolha um <a href="http://garann.github.io/template-chooser/">template engine</a> e renderize/pré-compile usando os executores de tarefas como gulp ou grunt</li> <li>verifique se há um arquivo \_<code>favicon.ico</code>\_ na raiz do site, ou seja, \_<code>/favicon.ico</code>\_. <a href="http://mathiasbynens.be/notes/rel-shortcut-icon">os navegadores solicitarão automaticamente</a> , mesmo que o ícone não seja mencionado no html. se você não tiver um \_<code>/favicon.ico</code>\_, isso resultará em muitos 404s, consumindo a largura de banda do servidor.</li> </ul><p><strong> seo (otimização de mecanismos de pesquisa) </strong></p><ul> <li>use urls "compatíveis com o mecanismo de pesquisa", ou seja, use \_<code>example.com/pages/45-article-title</code>\_ em vez de \_<code>example.com/index.php?page=45</code>\_</li> <li>ao usar \_<code>#</code>\_ para conteúdo dinâmico, altere \_<code>#</code>\_ para \_<code>#!</code>\_ e, em seguida, no servidor \_<code>$\_request["\_escaped\_fragment\_"]</code>\_, é o que o googlebot usa em vez de \_<code>#!</code>\_. em outras palavras, \_<code>./#!page=1</code>\_ se torna \_<code>./?\_escaped\_fragments\_=page=1</code>\_. além disso, para usuários que possam estar usando o ff.b4 ou o chromium, <code>history.pushstate({"foo":"bar"}, "about", "./?page=1");</code> é um ótimo comando. portanto, mesmo que a barra de endereço tenha mudado, a página não é recarregada. isso permite que você use \_<code>?</code>\_ em vez de \_<code>#!</code>\_ para manter o conteúdo dinâmico e também informar ao servidor quando você enviar por e-mail o link que estamos após esta página, e o ajax não precisa para fazer outro pedido extra.</li> <li>não use links que digam <a href="https://ux.stackexchange.com/questions/12100/why-shouldnt-we-use-the-word-here-in-a-textlink">"clique aqui"</a> . você está desperdiçando uma oportunidade de seo e isso torna as coisas mais difíceis para as pessoas com leitores de tela.</li> <li>tenha um <a href="http://www.sitemaps.org/">xml sitemap</a> , de preferência no local padrão \_<code>/sitemap.xml</code>\_.</li> <li>use <a href="http://googlewebmastercentral.blogspot.com/2009/02/specify-your-canonical.html">\_<code>&lt;link rel="canonical" ... /&gt;</code>\_</a> quando você tiver vários urls que apontam para o mesmo conteúdo, esse problema também pode ser solucionado em <a href="http://www.google.com/webmasters/">ferramentas do google para webmasters</a> .</li> <li>use <a href="http://www.google.com/webmasters/">ferramentas para webmasters do google</a> e <a href="http://www.bing.com/toolbox/webmaster">ferramentas para webmasters do bing</a> .</li> <li>instale <a href="http://www.google.com/analytics/">google analytics</a> logo no início (ou uma ferramenta de análise de código aberto como <a href="http://piwik.org/">piwik</a> /).</li> <li>saiba como <a href="https://en.wikipedia.org/wiki/robots\_exclusion\_standard">robots.txt</a> e as aranhas dos mecanismos de pesquisa funcionam.</li> <li>redirecione solicitações (usando \_<code>301 moved permanently</code>\_) solicitando \_<code>www.example.com</code>\_ para \_<code>example.com</code>\_ (ou o contrário) para impedir a divisão da classificação do google entre os dois sites.</li> <li>saiba que pode haver aranhas mal comportadas por aí.</li> <li>se você tiver conteúdo não textual, procure as extensões de mapa do site do google para vídeos, etc. há algumas informações boas sobre isso em <a href="https://stackoverflow.com/questions/72394/what-should-a-developer-know-before-building-a-public-web-site#167608">tim farley's answer</a> .</li> </ul><p><strong> tecnologia </strong></p><ul> <li>entenda <a href="http://www.ietf.org/rfc/rfc2616.txt"> http </a> e coisas como get, post, sessões, cookies e o que significa ser "sem estado".</li> <li>escreva seu <a href="http://www.w3.org/tr/xhtml1/"> xhtml </a> / <a href="http://www.w3.org/tr/rec-html40/"> html </a> e <a href="http://www.w3.org/tr/css2/"> css </a> de acordo com as especificações <a href="http://www.w3.org/tr/">w3c</a> e certifique-se de que eles <a href="http://validator.w3.org/">validam</a> /. o objetivo aqui é evitar os modos peculiares do navegador e, como bônus, facilitar o trabalho com navegadores não tradicionais, como leitores de tela e dispositivos móveis.</li> <li>entenda como o javascript é processado no navegador.</li> <li>entenda como o javascript, as folhas de estilo e outros recursos usados ​​por sua página são carregados e considere seu impacto no <em> desempenho percebido </em>. agora, é amplamente considerado adequado <a href="https://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-6-move-scripts-bottom-7200.html">mover scripts para o final das páginas</a> das suas páginas, com exceções que normalmente são coisas como aplicativos de análise ou shims html5.</li> <li>entenda como a sandbox javascript funciona, especialmente se você pretende usar iframes.</li> <li>esteja ciente de que o javascript pode e será desativado e que ajax é, portanto, uma extensão, não uma linha de base. mesmo que a maioria dos usuários o deixe ligado agora, lembre-se de que <a href="http://noscript.net/">noscript</a> está se tornando mais popular. embora os robôs de rastreamento modernos suportem a indexação de conteúdo gerado por javascript, considere usar a renderização no servidor para outros robôs ou usuários que desativaram o javascript.</li> <li>aprenda a diferença <a href="http://www.bigoakinc.com/blog/when-to-use-a-301-vs-302-redirect/">entre os redirecionamentos 301 e 302</a> (esse também é um problema de seo).</li> <li>aprenda o máximo possível sobre sua plataforma de implantação.</li> <li>considere usar uma <a href="https://stackoverflow.com/questions/11578819/css-reset-what-exactly-does-it-do">redefinir folha de estilos</a> ou <a href="http://necolas.github.com/normalize.css/">normalize.css</a> .</li> <li>considere estruturas javascript (como <a href="http://jquery.com/">jquery</a> , <a href="http://mootools.net/">mootools</a> , <a href="http://www.prototypejs.org/">prototype</a> , <a href="http://dojotoolkit.org">dojo</a> ou <a href="http://developer.yahoo.com/yui/3/">yui 3</a> ), que ocultará muitas diferenças do navegador ao usar javascript para manipulação de dom.</li> <li>reunindo o desempenho percebido e as estruturas js, considere usar um serviço como a <a href="http://developers.google.com/speed/libraries/devguide">api das bibliotecas do google</a> para carregar estruturas para que um navegador possa usar uma cópia da estrutura que ele já armazenou em cache, em vez de fazer o download de uma cópia duplicada. copiar do seu site.</li> <li>não reinvente a roda. antes de fazer qualquer coisa, procure um componente ou exemplo de como fazê-lo. há 99% de chance de alguém ter feito isso e lançado uma versão oss do código.</li> <li>por outro lado, não comece com 20 bibliotecas antes mesmo de decidir quais são suas necessidades. particularmente na web do lado do cliente, onde quase sempre é mais importante manter as coisas leves, rápidas e flexíveis.</li> </ul><p><strong> correção de erros </strong></p><ul> <li>entenda que você gastará 20% do seu tempo codificando e 80% dele mantendo, portanto, codifique de acordo.</li> <li>configure uma boa solução de relatório de erros.</li> <li>tenha um sistema para as pessoas entrarem em contato com você com sugestões e críticas.</li> <li>documente como o aplicativo funciona para futuras equipes de suporte e pessoas que realizam manutenção.</li> <li>faça backups frequentes! (e verifique se esses backups estão funcionando) tenha uma estratégia de restauração, não apenas uma estratégia de backup.</li> <li>use um sistema de controle de versão para armazenar seus arquivos, como <a href="http://subversion.apache.org/">subversion</a> , <a href="http://mercurial.selenic.com/">mercurial</a> ou <a href="http://git-scm.org">git</a> .</li> <li>não se esqueça de fazer seu teste de aceitação. estruturas como <a href="http://seleniumhq.org/">selenium</a> podem ajudar. especialmente se você automatizar completamente seus testes, talvez usando uma ferramenta de integração contínua, como <a href="http://jenkins-ci.org/">jenkins</a> .</li> <li>verifique se você possui log suficiente usando estruturas como <a href="http://logging.apache.org/log4j/">log4j</a> , <a href="http://logging.apache.org/log4net/">log4net</a> ou <a href="http://log4r.rubyforge.org/">log4r</a> . se algo der errado no seu site ao vivo, você precisará descobrir como.</li> <li>ao fazer o log, certifique-se de capturar as exceções tratadas e não tratadas. relate/analise a saída do log, pois mostrará onde estão os principais problemas em seu site.</li> </ul><p><strong> outros </strong></p><ul> <li>implemente monitoramento e análise do lado do servidor e do cliente (um deve ser proativo em vez de reativo).</li> <li>use serviços como uservoice e intercom (ou qualquer outra ferramenta similar) para manter contato constante com seus usuários.</li> <li>siga <a href="http://nvie.com/about/">vincent driessen</a> 's <a href="http://nvie.com/posts/a-successful-git-branching-model/">git branching model</a> </li> </ul><p>muitas coisas foram omitidas não necessariamente porque não são respostas úteis, mas porque são muito detalhadas, estão fora do escopo ou vão um pouco longe demais para alguém que deseja obter uma visão geral do que deve saber. sinta-se à vontade para editar isso também, provavelmente perdi algumas coisas ou cometi alguns erros.</p> Note-se que não se trata de "programação estrita unicode" per se, mas alguma experiência prática.


O que fizemos na minha empresa era criar uma biblioteca invólucro em torno da biblioteca ICU da IBM. A biblioteca wrapper tem uma interface UTF-8 e converte para UTF-16 quando é necessário chamar UTI. No nosso caso, nós não se preocupar muito com sucessos de desempenho. Quando o desempenho foi um problema, nós também fornecido interfaces de UTF-16 (usando o nosso próprio tipo de dados).


Aplicações poderia permanecer em grande parte como-é (usando caracteres), embora em alguns casos, eles precisam estar cientes de certas questões. Por exemplo, em vez de strncpy () usamos um invólucro que evita cortar sequências UTF-8. No nosso caso, isso é suficiente, mas também pode considerar cheques para combinar caracteres. Temos também wrappers para a contagem do número de codepoints, o número de grafemas, etc.


Quando a interface com outros sistemas, às vezes precisamos fazer composição caráter personalizado, assim você pode precisar de alguma flexibilidade lá (dependendo do aplicativo).


Nós não usamos wchar\_t. Usando UTI evita problemas inesperados na portabilidade (mas não outros problemas inesperados, é claro :-). Codificação ANSI é um termo um pouco genérico usado para se referir à página de código padrão em um sistema, normalmente o Windows. Ele é mais apropriadamente referido como [o Windows-1252](http://en.wikipedia.org/wiki/Windows-1252) em sistemas ocidentais / americanos. (Pode representar certas outras [páginas de código do Windows](http://en.wikipedia.org/wiki/Windows_code_page) em outros sistemas.) Esta é essencialmente uma [extensão do conjunto de caracteres ASCII](http://en.wikipedia.org/wiki/Extended_ASCII) na medida em que inclui todos os caracteres ASCII com um 128 códigos de caracteres adicionais. Esta diferença é devida ao facto de que codifica para o "ANSI" é de 8 bits em vez de 7-bit como ASCII é (ASCII é quase sempre codificada hoje em dia como bytes de 8 bits, com o [MSB](https://en.wikipedia.org/wiki/Most_significant_bit) definida como 0). Veja o artigo para uma explicação de por que essa codificação é geralmente referida como ANSI.


O nome "ANSI" é um equívoco, uma vez que não correspondem a qualquer padrão ANSI real, mas o nome pegou. ANSI não é a mesma como UTF-8. Opção 1 é de longe o padrão. A fraqueza texto simples geralmente é superado pela aplicação SSL durante o login para que a senha é, pelo menos criptografados durante o trânsito.


**Edit:** Eu sugiro que você siga a resposta aceitos para essa pergunta.


Não se esqueça de exigir um [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce) para o seu pedido. Isso ajudará a protegê-lo contra ataques de repetição.


**Editar o segundo:** Wayne cuidadosamente mencionou que você deve [sal](https://stackoverflow.com/questions/674904/salting-your-password-best-practices) sua senha antes de hash. Aqui estão algumas dicas básicas:


1. Não importa se o seu sal é um prefixo, postfix, ou infix
2. Seu sal deve ser grande, aleatório, e complexo.
3. Seu sal deve ser único por valor salgada. O sal em si não precisa ser criptografados. <pre><code>parsed = json &amp;&amp; json.length &gt;= 2 ? json.parse(json) : nil </code></pre><p>mas realmente a biblioteca deve ser capaz de lidar com este caso e retornar nulo. navegadores da web com suporte json interno parecem funcionar exatamente como você espera, afinal.</p><hr><p>ou para fazer isso com um mini patch apenas um pouco intrusivo:</p><pre><code>module json def self.parse\_nil(json) json.parse(json) if json &amp;&amp; json.length &gt;= 2 end end parsed = json.parse\_nil(json) </code></pre> <p>a maneira mais fácil é anexar a string de origem com algum parâmetro aleatório, que é ignorado no lado do servidor</p><pre><code>&lt;script src="mysavefiles.json?nocache=123" &gt;&lt;/script&gt; </code></pre><p>uma solução seria gerar o elemento de script usando javascript e acrescentar a hora atual como esta:</p><pre><code>var el = document.createelement( script ); el.src = 'mysavefiles.json?nocache=' + (new date()).gettime(); document.head.appendchild( el ); </code></pre><p>dessa forma, o navegador nunca armazenará em cache o arquivo json, pois parece ser um arquivo diferente (devido ao parâmetro) em cada chamada.</p> <p>lidar com vários níveis de citação (na verdade, vários níveis de análise/interpretação) pode ser complicado. isso ajuda a manter algumas coisas em mente:</p><ul> <li>cada “nível de citação” pode envolver potencialmente uma linguagem diferente.</li> <li>as regras de cotação variam de acordo com o idioma.</li> <li>ao lidar com mais de um ou dois níveis aninhados, geralmente é mais fácil trabalhar "de baixo para cima" (ou seja, do interior para o exterior).</li> </ul><h1>níveis de citação</h1><p>vejamos seus comandos de exemplo.</p><pre><code>pgrep -fl java | grep -i datanode | awk '{print $1}' </code></pre><p>seu primeiro exemplo de comando (acima) usa quatro idiomas: seu shell, o regex em <em> pgrep </em>, o regex em <em> grep </em> (que pode ser diferente da linguagem regex em <em> pgrep </em>) e <em> awk </em>. existem dois níveis de interpretação envolvidos: o shell e um nível após o shell para cada um dos comandos envolvidos. existe apenas um nível explícito de citação (shell citação em <em> awk </em>).</p><pre><code>ssh host … </code></pre><p>em seguida, você adicionou um nível de <em> ssh </em> no topo. este é efetivamente outro nível de shell: <em> ssh </em> não interpreta o comando em si, ele o entrega a um shell na extremidade remota (via (por exemplo) <code>sh -c …</code>) e que shell interpreta a string.</p><pre><code>ssh host "sudo su user -c …" </code></pre><p>então, você perguntou sobre a adição de outro nível de shell no meio usando <em> su </em> (via <em> sudo </em>, que não interpreta seus argumentos de comando, portanto, podemos ignorá-lo). neste ponto, você tem três níveis de aninhamento em andamento (<em> awk </em> → shell, shell → shell (<em> ssh </em>), shell → shell (<em> su user -c </em>), então aconselho usar a abordagem “de baixo para cima”. vou assumir que seus shells são compatíveis com bourne (por exemplo <em> sh </em>, <em> ash </em> , <em> traço </em>, <em> ksh </em>, <em> bash </em>, <em> zsh </em>, etc.). algum outro tipo de shell (<em> fish </em>, <em> rc </em>, etc.) pode exigir sintaxe diferente, mas o método ainda se aplica.</p><h1>debaixo para cima</h1><ol> <li>formule a string que deseja representar no nível mais interno.</li> <li>selecione um mecanismo de citações do repertório de citações do idioma seguinte.</li> <li>cite a string desejada de acordo com o mecanismo de cotação selecionado. <ul> <li>freqüentemente, há muitas variações de como aplicar qual mecanismo de cotação. fazer manualmente é geralmente uma questão de prática e experiência. ao fazer isso de forma programática, geralmente é melhor escolher o mais fácil de acertar (geralmente o “mais literal” (menos escapes)).</li> </ul> </li> <li>opcionalmente, use a string entre aspas resultante com código adicional.</li> <li>se você ainda não atingiu o nível desejado de citação/interpretação, pegue a string entre aspas resultante (mais qualquer código adicionado) e use-a como string inicial na etapa 2.</li> </ol><h1>a semântica das citações varia</h1><p>o que se deve ter em mente aqui é que cada idioma (nível de citação) pode fornecer semânticas ligeiramente diferentes (ou mesmo semânticas drasticamente diferentes) para o mesmo personagem de citação.</p><p>a maioria das linguagens tem um mecanismo de citação “literal”, mas eles variam exatamente em quão literais são. a aspa simples de shells do tipo bourne é literal (o que significa que você não pode usá-la para citar um caractere de aspas simples). outras linguagens (perl, ruby) são menos literais porque interpretam <strong>algumas</strong> sequências de barra invertida dentro de regiões entre aspas simples não literalmente (especificamente, <code>\\</code> e <code>\'</code> resulta em <code>\</code> e <code>'</code>, mas outras sequências de barra invertida são, na verdade, literais).</p><p>você terá que ler a documentação de cada um de seus idiomas para entender suas regras de cotação e a sintaxe geral.</p><h1>seu exemplo</h1><p>o nível mais interno do seu exemplo é um programa <em> awk </em>.</p><pre><code>{print $1} </code></pre><p>você vai incorporar isso em uma linha de comando do shell:</p><pre><code>pgrep -fl java | grep -i datanode | awk … </code></pre><p>precisamos proteger (no mínimo) o espaço e o <code>$</code> no programa <em> awk </em>. a escolha óbvia é usar aspas simples no shell em todo o programa.</p><ul> <li><code>'{print $1}'</code></li> </ul><p>no entanto, existem outras opções:</p><ul> <li><code>{print\ \$1}</code> escape diretamente do espaço e <code>$</code></li> <li><code>{print' $'1}</code> aspas simples apenas o espaço e <code>$</code></li> <li><code>"{print \$1}"</code> aspas duplas o todo e escapar de <code>$</code></li> <li><code>{print" $"1}</code> aspas duplas apenas o espaço e <code>$</code><br> isso pode estar distorcendo um pouco as regras (sem escape <code>$</code> no final de uma string entre aspas duplas é literal), mas parece funcionar na maioria dos shells.</li> </ul><p>se o programa usasse uma vírgula entre as chaves de abertura e fechamento, também precisaríamos citar ou escapar a vírgula ou as chaves para evitar a “expansão da chave” em alguns shells.</p><p>nós escolhemos <code>'{print $1}'</code> e incorporá-lo ao resto do “código” shell:</p><pre><code>pgrep -fl java | grep -i datanode | awk '{print $1}' </code></pre><p>em seguida, você queria executar isso via <em> su </em> e <em> sudo </em>.</p><pre><code>sudo su user -c … </code></pre><p><code>su user -c …</code> é como <code>some-shell -c …</code> (exceto rodando em algum outro uid), então <em> su </em> apenas adiciona outro nível de shell. <em> sudo </em> não interpreta seus argumentos, então não adiciona nenhum nível de citação.</p><p>precisamos de outro nível de shell para nossa string de comando. podemos escolher aspas simples novamente, mas temos que dar tratamento especial às aspas simples existentes. a maneira usual é assim:</p><pre><code>'pgrep -fl java | grep -i datanode | awk '\''{print $1}'\' </code></pre><p>existem quatro strings aqui que o shell irá interpretar e concatenar: a primeira string entre aspas simples (<code>pgrep … awk</code>), uma aspa simples de escape, o programa de aspas simples <em> awk </em>, outra aspa simples de escape.</p><p>existem, é claro, muitas alternativas:</p><ul> <li><code>pgrep\ -fl\ java\ \|\ grep\ -i\ datanode\ \|\ awk\ \'{print\ \$1}</code> fuja de tudo que é importante</li> <li><code>pgrep\ -fl\ java\|grep\ -i\ datanode\|awk\ \'{print\$1}</code> o mesmo, mas sem espaços em branco supérfluos (mesmo no programa <em> awk </em>!)</li> <li><code>"pgrep -fl java | grep -i datanode | awk '{print \$1}'"</code> aspas duplas, escape de <code>$</code></li> <li><code>'pgrep -fl java | grep -i datanode | awk '"'"'{print \$1}'"'"</code> sua variação; um pouco mais longo do que o normal devido ao uso de aspas duplas (dois caracteres) em vez de escapes (um caractere)</li> </ul><p>usar citações diferentes no primeiro nível permite outras variações neste nível:</p><ul> <li><code>'pgrep -fl java | grep -i datanode | awk "{print \$1}"'</code></li> <li><code>'pgrep -fl java | grep -i datanode | awk {print\ \$1}'</code></li> </ul><p>incorporar a primeira variação na linha de comando <em> sudo </em>/* su * fornece o seguinte:</p><pre><code>sudo su user -c 'pgrep -fl java | grep -i datanode | awk '\''{print $1}'\' </code></pre><p>você pode usar a mesma string em qualquer outro contexto de nível de shell (por exemplo, <code>ssh host …</code>).</p><p>em seguida, você adicionou um nível de <em> ssh </em> no topo. este é efetivamente outro nível de shell: <em> ssh </em> não interpreta o comando em si, mas o entrega a um shell na extremidade remota (via (por exemplo) <code>sh -c …</code>) e que shell interpreta a string.</p><pre><code>ssh host … </code></pre><p>o processo é o mesmo: pegue a string, escolha um método de cotação, use-a, incorpore-a.</p><p>usando aspas simples novamente:</p><pre><code>'sudo su user -c '\''pgrep -fl java | grep -i datanode | awk '\'\\\'\''{print $1}'\'\\\' </code></pre><p>agora, existem onze strings que são interpretadas e concatenadas: <code>'sudo su user -c '</code>, aspas simples com escape, <code>'pgrep … awk '</code>, aspas simples de escape, barra invertida de escape, duas aspas simples de escape, o programa entre aspas simples <em> awk </em>, aspas simples de escape, barra invertida de escape e um aspas simples com escape final.</p><p>a forma final é parecida com esta:</p><pre><code>ssh host 'sudo su user -c '\''pgrep -fl java | grep -i datanode | awk '\'\\\'\''{print $1}'\'\\\' </code></pre><p>é um pouco complicado digitar à mão, mas a natureza literal da citação única do shell torna mais fácil automatizar uma ligeira variação:</p><pre><code>#!/bin/sh sq() { # single quote for bourne shell evaluation # change ' to '\'' and wrap in single quotes. # if original starts/ends with a single quote, creates useless # (but harmless) '' at beginning/end of result. printf '%s\n' "$*" | sed -e "s/'/'\\\\''/g" -e 1s/^/\'/ -e \$s/\$/\'/ } # some shells (ksh, bash, zsh) can do something similar with %q, but # the result may not be compatible with other shells (ksh uses $'...', # but dash does not recognize it). # # sq() { printf %q "$*"; } ap='{print $1}' s1="pgrep -fl java | grep -i datanode | awk $(sq "$ap")" s2="sudo su user -c $(sq "$s1")" ssh host "$(sq "$s2")" </code></pre>