Divers didacticiels croisés, diverses pratiques et diverses questions-réponses en ligne. En plus du simple JSONP, de nombreuses personnes disent que les COR ne fonctionnent pas et qu'ils manquent toujours d'une ou deux configurations clés. Cet article veut seulement résoudre le problème, et tout le code a été pratiqué par vous-même.
Cet article résout des problèmes tels que Get, Post, Data et Cookies en domaine croisé.
Cet article ne parlera que des demandes de GET et de la publication des demandes. Les lecteurs doivent comprendre les demandes de publication comme toutes les autres méthodes de demande, à l'exception des demandes d'obtention.
Jsonp
JSONP utilise le principe selon lequel le navigateur n'a aucune restriction homologique sur les références de ressources de script et insère dynamiquement une balise de script et sera exécutée immédiatement après le chargement de la ressource sur la page. JSONP est un protocole de transmission informel. L'un des points clés de ce protocole est de permettre aux utilisateurs de passer un rappel ou de définir une méthode de rappel au début, et les paramètres sont donnés au serveur. Lorsque le serveur renvoie les données, le paramètre de rappel sera utilisé comme nom de fonction pour envelopper les données JSON, afin que le client puisse personnaliser ses propres fonctions pour traiter automatiquement les données de retour.
JSONP ne prend en charge que les demandes GET, mais pas d'autres types de demandes HTTP telles que la publication. Il ne prend en charge que les demandes HTTP inter-domaines. Il ne peut pas résoudre le problème de la façon de passer des appels JavaScript entre deux pages dans différents domaines. L'avantage de JSONP est qu'il prend en charge les navigateurs à l'ancienne, et les inconvénients sont également évidents: il nécessite la personnalisation du client et du serveur pour le développement. Les données renvoyées par le serveur ne peuvent pas être des données JSON standard, mais les données enveloppées par rappel.
Le principe de JSONP est très simple et utilise l'idée de [il n'y a pas de problème de domaine croisé lorsque le front-end demande des ressources statiques].
Mais il ne prend en charge que GET, les supports seulement Get, seuls les supports GET.
Notez que comme cette méthode est appelée JSONP, les données backend doivent utiliser les données JSON. Vous ne pouvez pas faire une chaîne ou quelque chose avec désinvolture, sinon vous trouverez le résultat inexplicable.
Méthode d'écriture de jQuery frontal
$ .ajax ({type: "get", URL: BUSURL + "/ JSONP / GET", DataType: "JSONP", Success: Function (Response) {$ ("# réponse"). Val (JSON.Strifify (Response));}});DataType: "JSONP". À l'exception de cela, les autres configurations sont les mêmes que les demandes normales.
Configuration de Springmvc backend
Si vous utilisez également SpringMVC, configurez un conseil JSONP, afin que chaque méthode de contrôleur que nous écrivons ne doit pas se demander si le client demande JSONP et que Spring le gérera automatiquement en conséquence.
@ControlleRAdvicePublic Class JSONPADvice étend AbstractJSonpResponseBodyAdvice {public JSonPadvice () {// De cette manière, si la demande contient le paramètre de rappel, Spring saura qu'il s'agit d'une demande JSONP super ("callback"); }}La méthode d'écriture ci-dessus nécessite que la version SpringMVC ne soit pas inférieure à 3,2, et je peux seulement dire que vous devez mettre à niveau.
Configuration backend nonpringmvc
Quand j'ai commencé à travailler, Struts2 était toujours populaire. Après quelques années, SpringMVC a essentiellement dominé le marché intérieur.
Soyez paresseux, voici un pseudo-code, et cliquez sur la méthode de Wrap avant que notre méthode ne revienne à l'avant:
@ControlleRAdvicePublic Class JSONPADvice étend AbstractJSonpResponseBodyAdvice {public JSonPadvice () {// De cette manière, si la demande contient le paramètre de rappel, Spring saura qu'il s'agit d'une demande JSONP super ("callback"); }}Cors
Partage de ressources d'origine intermédiaire
CORS est un moyen que les navigateurs modernes prennent en charge les demandes de ressources inter-domaines. Le nom complet est "Cross-Originresourcesharing". Lors de l'envoi d'une demande à l'aide de XMLHTTPREQUEST, le navigateur constate que la demande ne respecte pas la stratégie d'origine même et ajoutera un en-tête de demande à la demande: Origin. L'arrière-plan effectue une série de traitements. S'il est déterminé à accepter la demande, un en-tête de réponse est ajouté au résultat de retour: Access-Control-Allow-Origin; Le navigateur détermine si l'en-tête correspondant contient la valeur d'origine. S'il y en a, le navigateur traitera la réponse et nous pouvons obtenir les données de réponse. Si le navigateur n'inclut pas le navigateur, nous ne pouvons pas obtenir les données de réponse.
CORS et JSONP utilisent le même objectif, mais il est plus puissant que JSONP. CORS prend en charge tous les types de demandes de navigateur, et la quantité de données demandées est plus grande et plus ouverte et concise. Le serveur n'a besoin que de renvoyer les données traitées directement et il n'y a pas besoin de traitement spécial.
Après tout, JSONP ne prend en charge que les demandes de GET, qui ne peuvent certainement pas répondre à tous nos besoins de demande, donc les COR doivent être déplacés.
Les développeurs Web nationaux sont encore assez difficiles. Les utilisateurs ne mettent pas à niveau leurs navigateurs et le boss souhaite toujours que les développeurs soient compatibles.
CORS prend en charge les navigateurs suivants. À l'heure actuelle, les problèmes du navigateur deviennent de moins en moins importants, et même Taobao ne prend pas en charge IE7 ~~~
Chrome 3+
Firefox 3.5+
Opéra 12+
Safari 4+
Internet Explorer 8+
Méthode d'écriture de jQuery frontal
Regardez simplement le code:
$ .ajax ({type: "post", URL: substanl + "/ jsonp / post", dataType: 'json', crossdomain: true, xhrfields: {withcredentials: true}, data: {name: "name_from_frontend"}, réussite: fonction (réponse) {console.log (réponse) // $ ("# réponse"). Val (json.stringify (réponse));}});DataType: "JSON", voici JSON, pas JSONP, pas JSONP, pas JSONP.
CrossDomain: Vrai, ici signifie utiliser des demandes de domaine inter-intermédiaire
xhrfields: {withCredentials: true}, afin que la configuration puisse apporter les cookies, sinon nous ne pouvons même pas maintenir la session, et de nombreuses personnes sont piégées ici. Bien sûr, si vous n'avez pas cette exigence, vous n'avez pas besoin de configurer cela.
Configuration de Springmvc backend
Pour la plupart des projets Web, il existe généralement des classes de configuration liées à MVC, qui sont héritées de WebMVCConfiGureAdapter. Si vous utilisez également SpringMVC 4.2 ou supérieur, ajoutez simplement cette méthode comme ce qui suit:
@ConfigurationPublic class WebConfig étend webmvcconfigurerAdapter {@Override public void addCorsMappings (CorsEgistry Registry) {registry.addmapping ("/ ** / *"). ALLORIGIGINS ("*"); }}Si vous êtes malheureusement dans votre projet, la version SpringMVC est inférieure à 4.2, vous devez "sauver le pays via les courbes":
classe publique CrossDomainFilter étend une fois PEperRequestFilter {@Override Protected void DofilteRINNERNAL (HttpServleRequest Request, HttpservletResponse Response, FilterChain FilterChain) Servlexception, ioException {Response.Addheader (If If newo-control-allow-ogin "," * "); Recherchez Response.Addheader ("Access-Control-Allow-Credentials", "True"); Response.AddHeader ("Access-Control-Allow-Methods", "Get, Post, Put, Delete"); Response.Addheader ("Access-Control-Allow-Headers", "Content-Type"); FilterChain.Dofilter (demande, réponse); }}Configurer le filtre dans web.xml:
<filter> <filter-name> CrossDomainFilter </ Filter-Name> <Filter-Class> com.javadoop.filters.crossdomainfilter </filter-Class> </filter> <filter-mapping> <filter-name>
Il existe de nombreux projets qui utilisent Shiro, et vous pouvez également configurer des filtres Shiro, donc je ne les présenterai pas ici.
Notez que je parle de configurations très générales, qui peuvent être configurées dans de telles configurations générales pour la plupart des projets. Les lecteurs doivent savoir comment faire correspondre les configurations comme "*" dans l'article.
Si le lecteur constate que le navigateur invite que le symbole '*' ne peut pas être utilisé, le lecteur peut obtenir le référent (request.getheader ("référer") dans l'en-tête de demande en fonction de l'objet de demande dans le filtre ci-dessus, puis définir dynamiquement "Access-Control-allow-Origin":
String référer = request.getheader ("référente"); if (stringUtils.isnotblank (référente)) {url url = new URL (référer); String Origin = url.getProtoCol () + ": //" + url.Gethost (); Response.Addheader ("Access-Control-Allow-Origin", Origin);} else {Response.Addheader ("Access-Control-Allow-Origin", "*");}Écriture avant non-jquery
Les jours où vous mangez jQuery avec une astuce ont complètement disparu. Ici, je vais parler de la façon de résoudre le problème du post-domaine post si vous n'utilisez pas jQuery.
Présentons un JS natif:
fonction createCorsRequest (méthode, url) {var xhr = new xmlHttpRequest (); if ("withCredentials" dans xhr) {// S'il y a l'attribut withCredentials, c'est définitivement un objet XMLHTTPRequest2. Regardez le troisième paramètre xhr.open (méthode, URL, true); } else if (typeof xdomainRequest! = "Undefined") {// Cet objet est utilisé par IE pour demander à travers les domaines xhr = new xdomainRequest (); xhr.open (méthode, URL); } else {// Si c'est le cas, malheureusement, le navigateur ne prend pas en charge CORS xhr = null; } return xhr;} var xhr = createCorsRequest ('get', url); if (! xhr) {lancer une nouvelle erreur ('Cors non pris en charge');}Parmi eux, Chrome, Firefox, Opera et Safari, ces navigateurs "adaptés aux programmeurs" utilisent des objets XMLHTTPRequest2. IE utilise xDomainRequest.
Résumer
Ce qui précède consiste à résoudre rapidement les problèmes de demande de domaine croisé: JSONP et CORS. J'espère que ce sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à d'autres sujets connexes sur ce site. S'il y a des lacunes, veuillez laisser un message pour le signaler!