Table des matières
Comment utiliser
Prenons nginx comme exemple
server A
server 2
Remarque
Page proxy + iframe pour obtenir un accès inter-domaines
Maison interface Web js tutoriel Solution complète ultra-détaillée aux problèmes inter-domaines (avec exemples)

Solution complète ultra-détaillée aux problèmes inter-domaines (avec exemples)

Jan 14, 2019 am 10:05 AM
javascript nginx node.js 跨域

Ce que cet article vous apporte est une solution très détaillée et complète aux problèmes inter-domaines (avec des exemples). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Problèmes inter-domaines courants

Brève description

En tant que débutant front-end, je ne connais que JSONP et CORS en cross -domaine. Je ne l'ai pas compris en profondeur. Mais à mesure que le recrutement printanier approche, même les recrues doivent battre des ailes. J'ai soigneusement étudié les problèmes inter-domaines ces derniers jours et j'ai écrit cet article, dans l'espoir d'être utile aux développeurs. Avant de lire cet article, j'espère que vous avez quelques connaissances sur les points suivants.

Politique de même origine du navigateur

nodejs

iframe

docker, nginx

Pourquoi devrions-nous étudier les problèmes inter-domaines

Parce que la politique de même origine du navigateur stipule que les clients d'un certain domaine ne peuvent pas lire ou écrire des ressources dans un autre domaine sans autorisation explicite. Dans le développement réel, le front-end et le back-end sont souvent séparés l'un de l'autre, et les déploiements de projets front-end et back-end ne se font souvent pas au sein d'un serveur ou sous différents ports d'un serveur. Si le front-end souhaite obtenir les données du back-end, il doit lancer une requête. Si elle est traitée correctement, elle sera limitée par la politique de même origine du navigateur. Le backend peut recevoir la demande et renvoyer les données, mais le frontend ne peut pas recevoir les données.

Plusieurs méthodes inter-domaines

L'inter-domaine peut être grossièrement divisé en deux objectifs

Lorsque le front-end et le back-end sont séparés , le front-end utilise le Cross-domain

Cross-domain pour la communication des pages front-end dans différents domaines

Cross-domain pour la séparation front-end et back-end

Partage de ressources inter-origines (CORS))

CORS est une solution de partage de ressources inter-domaines afin de résoudre les problèmes inter-domaines, en ajoutant une série d'en-têtes de requête et de réponses. en-têtes, la transmission des données entre sites est standardisée et sécurisée

Les en-têtes de requêtes incluent principalement

En-tête de requête Explication
请求头 解释
Origin Origin头在跨域请求或预先请求中,标明发起跨域请求的源域名。
Access-Control-Request-Method Access-Control-Request-Method头用于表明跨域请求使用的实际HTTP方法
Access-Control-Request-Headers Access-Control-Request-Headers用于在预先请求时,告知服务器要发起的跨域请求中会携带的请求头信息
Origin

L'en-tête Origin indique le nom de domaine source de la requête cross-domaine dans une requête cross-domaine ou une pré-demande.
Access-Control-Request-Method L'en-tête Access-Control-Request-Method est utilisé pour indiquer l'utilisation de requêtes inter-domaines La méthode HTTP réelle
Access-Control-Request-Headers
响应头 解释
Access-Control-Allow-Origin Access-Control-Allow-Origin头中携带了服务器端验证后的允许的跨域请求域名,可以是一个具体的域名或是一个*(表示任意域名)。
Access-Control-Expose-Headers Access-Control-Expose-Headers头用于允许返回给跨域请求的响应头列表,在列表中的响应头的内容,才可以被浏览器访问。
Access-Control-Max-Age Access-Control-Max-Age用于告知浏览器可以将预先检查请求返回结果缓存的时间,在缓存有效期内,浏览器会使用缓存的预先检查结果判断是否发送跨域请求。
Access-Control-Allow-Methods Access-Control-Allow-Methods用于告知浏览器可以在实际发送跨域请求时,可以支持的请求方法,可以是一个具体的方法列表或是一个*(表示任意方法)。
Access-Control-Request-Headers est utilisée lors d'une demande préalable, informer le serveur des informations d'en-tête de requête qui seront contenues dans la requête inter-domaines à lancer
La réponse l'en-tête comprend principalement
En-tête de réponse Explication th>
Access-Control-Allow-Origin L'en-tête Access-Control-Allow-Origin porte le Le nom de domaine de demande inter-domaines autorisé après vérification côté serveur peut être un nom de domaine spécifique ou un * (indiquant n'importe quel nom de domaine).
Access-Control-Expose-Headers L'en-tête Access-Control-Expose-Headers est utilisé pour permettre aux retours de se croiser -demandes de domaine Une liste d'en-têtes de réponse Seul le contenu des en-têtes de réponse de la liste est accessible au navigateur.
Access-Control-Max-Age Access-Control-Max-Age est utilisé pour indiquer au navigateur qu'il peut pré-vérification L'heure à laquelle le résultat de la requête est mis en cache. Pendant la période de validité du cache, le navigateur utilisera les résultats de la pré-vérification mis en cache pour déterminer s'il doit envoyer une requête inter-domaines.
Access-Control-Allow-Methods Access-Control-Allow-Methods est utilisé pour indiquer au navigateur qu'il peut envoyer réellement Lors des requêtes inter-domaines, les méthodes de requête prises en charge peuvent être une liste de méthodes spécifiques ou un * (indiquant n'importe quelle méthode).

Comment utiliser

  • Le client n'a qu'à définir l'en-tête de la requête en fonction de la spécification.

  • Le serveur reconnaît et renvoie l'en-tête de réponse correspondant selon la spécification, ou installe le plug-in correspondant, modifie le fichier de configuration du framework correspondant, etc. Cela dépend du langage et du framework utilisés par le serveur

Exemple de configuration SpringBoot CORS

Un morceau de code sur la configuration CORS dans un Spring Boot project

HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        String temp = request.getHeader("Origin");
        httpServletResponse.setHeader("Access-Control-Allow-Origin", temp);
        // 允许的访问方法
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
//         Access-Control-Max-Age 用于 CORS 相关配置的缓存
        httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
        httpServletResponse.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept,token");
        httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
Copier après la connexion

JSONP Cross-domain

Le principe de jsonp est d'utiliser la balise <script> Créez donc dynamiquement une balise <srcipt>, src est l'interface de destination + obtenir le paquet de données + le nom de la fonction pour le traitement des données. Après avoir reçu la requête GET, l'arrière-plan analyse et renvoie le nom de la fonction (données) au front-end. La balise <script> du front-end exécute dynamiquement la fonction de traitement <br/>Observez le code suivant </script>

Front. -end code

nbsp;html>


    <meta>
    <title>Title</title>


<script>
    var script = document.createElement(&#39;script&#39;);
    script.type = &#39;text/javascript&#39;;

    // 传参并指定回调执行函数为getData
    script.src = &#39;http://localhost:8080/users?username=xbc&callback=handleData&#39;;
    document.body.appendChild(script);
    // 回调执行函数
    function handleData(res) {
        data = JSON.stringify(res)
        console.log(data);
    }
</script>

Copier après la connexion

Code backend (nodejs)

var querystring = require('querystring');
var http = require('http');
var server = http.createServer();

server.on('request', function(req, res) {
    var params = querystring.parse(req.url.split('?')[1]);
    var fn = params.callback;

    // jsonp返回设置
    res.writeHead(200, { 'Content-Type': 'text/javascript' });
    var data = {
        user: 'xbc',
        password: '123456'
    }
    res.write(fn + '(' + JSON.stringify(data) + ')');

    res.end();
});

server.listen('8080');
console.log('Server is running at port 8080...');
Copier après la connexion

Dans cet exemple, la résolution reçue par le frontend est comme ceci

Solution complète ultra-détaillée aux problèmes inter-domaines (avec exemples)

La page d'accueil ressemble à ceci

Solution complète ultra-détaillée aux problèmes inter-domaines (avec exemples)

Remarque

JSONP utilise , seules les requêtes GET peuvent alors être prises en charge. Les autres requêtes ne peuvent pas être mises en œuvre

Le proxy inverse nginx réalise des idées inter-domaines

Idées

Étant donné que le navigateur a des restrictions de politique de même origine, nous mettons le projet front-end Ne suffit-il pas de mettre l'adresse de l'interface api demandée par le front-end sous la même source ? Combinés au proxy inverse fourni par le serveur Web, les problèmes inter-domaines peuvent être résolus sans aucune configuration sur le front-end ou le back-end.

Prenons nginx comme exemple

La véritable adresse d'arrière-plan du backend : http://xxx.xxx.xxx.xxx:8085 L'adresse d'arrière-plan du projet Spring Boot déployé à l'aide de Tomcat s'appelle gsms_test

Adresse du serveur nginx : http://xxx.xxx.xxx.xxx:8082

Tomcat et nginx sont tous deux configurés avec Docker et la redirection de port est effectuée

Conditions d'utilisation : L'environnement de développement est un système Linux

nginx /etc/nginx/conf.d/default.confLe code de configuration est le suivant

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        # root   /usr/share/nginx/html/dist; # 前端项目路径
        # index  index.html index.htm;
        proxy_pass http://localhost:8001/; # 前端本机地址,实现自动更新
        autoindex on;
        autoindex_exact_size on;
        autoindex_localtime on;
    }

    location /gsms_test/ {
        proxy_pass 后端真实地址;
    }

    

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
Copier après la connexion

Les pages de différents domaines communiquent entre domaines

window.name + iframe cross-domain

window.name Ce sont les données partagées par une fenêtre dans le navigateur. Elles existent toujours après chargement sur différentes pages (ou même différents noms de domaine) (la valeur ne changera pas si elle n'est pas modifiée). ), et peut supporter très longtemps valeur du nom (2 Mo). Par exemple Si une page du domaine a souhaite obtenir des données d'une page du domaine b, vous pouvez modifier la valeur window.name dans le domaine b. Basculez le domaine a vers le domaine b et revenez en arrière pour obtenir la valeur window.name du domaine b. Mais nous ne voulons certainement pas changer de page pendant le développement, nous devons donc le combiner avec iframe.

Exemple (implémenté avec thinkjs)

a Le code de domaine est le suivant

nbsp;html>


<meta>
<title>A 域</title>


<h1 id="server-A">server A</h1>
<script>
    function getData() {
        var iframe = document.getElementById(&#39;proxy&#39;);
        iframe.onload = function () {
            var name = iframe.contentWindow.name; // 获取iframe窗口里的window.name值
            console.log(name)
        }
        // 由于iframe信息传递也受同源策略限制,所以在window.name被B域修改后,将iframe转回A域下。以便获取iframe的window.name值
        iframe.src = &#39;http://127.0.0.1:8360/sub.html&#39; 
    }
</script>
<iframe>        </iframe>

Copier après la connexion

b Le code de domaine

nbsp;html>


<meta>
<title>New ThinkJS Application</title>


  <h1 id="server">server 2</h1>
<script>
  window.name = &#39;user: xbc&#39;;
</script>

Copier après la connexion

Remarque

En raison de la restriction de la politique de même origine, la page parent obtient des informations incomplètes à partir de la page iframe inter-domaines, elle doit donc être convertie en domaine A. après que le window.name de l'iframe soit modifié par le domaine B. N'importe quelle page (window.name ne doit pas être modifiée de ce côté) est obtenue.

Page proxy + iframe pour obtenir un accès inter-domaines

Étant donné que l'accès mutuel entre iframe et la page parent est également restreint par la politique de même origine, une page proxy est requise pour obtenir un accès inter-domaines accéder.

Solution complète ultra-détaillée aux problèmes inter-domaines (avec exemples)

Personnellement, je pense que c'est un peu gênant. Si vous êtes intéressé, veuillez voir comment le front-end utilise une page proxy. pour résoudre le problème de l'accès inter-domaines iframe ?

Résumé

Les méthodes ci-dessus sont toutes des méthodes inter-domaines que j'ai utilisées ou testées. Il existe également des méthodes inter-domaines telles que postMessage et WebSocket, qui n'ont jamais été utilisés auparavant. Contacter sans explication. Divers problèmes doivent être pris en compte spécifiquement lors de l'utilisation de ces méthodes dans un projet

情况 方法
只有GET请求 JSONP
对兼容性及浏览器版本无要求 CORS
对兼容性及浏览器版本有要求 iframe 或 服务器反向代理(linux 环境下开发)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment vérifier si Nginx est démarré Comment vérifier si Nginx est démarré Apr 14, 2025 pm 01:03 PM

Comment confirmer si Nginx est démarré: 1. Utilisez la ligne de commande: SystemCTl Status Nginx (Linux / Unix), netStat -ano | Findstr 80 (Windows); 2. Vérifiez si le port 80 est ouvert; 3. Vérifiez le message de démarrage NGINX dans le journal système; 4. Utilisez des outils tiers, tels que Nagios, Zabbix et Icinga.

Comment configurer le nom de domaine du serveur cloud dans nginx Comment configurer le nom de domaine du serveur cloud dans nginx Apr 14, 2025 pm 12:18 PM

Comment configurer un nom de domaine NGINX sur un serveur cloud: Créez un enregistrement A pointant vers l'adresse IP publique du serveur cloud. Ajoutez des blocs d'hôtes virtuels dans le fichier de configuration Nginx, en spécifiant le port d'écoute, le nom de domaine et le répertoire racine du site Web. Redémarrez Nginx pour appliquer les modifications. Accéder à la configuration du test de nom de domaine. Autres notes: Installez le certificat SSL pour activer HTTPS, assurez-vous que le pare-feu autorise le trafic Port 80 et attendez que la résolution DNS prenne effet.

Comment vérifier la version nginx Comment vérifier la version nginx Apr 14, 2025 am 11:57 AM

Les méthodes qui peuvent interroger la version Nginx sont: utilisez la commande nginx -v; Afficher la directive de version dans le fichier nginx.conf; Ouvrez la page d'erreur Nginx et affichez le titre de la page.

Comment démarrer le serveur Nginx Comment démarrer le serveur Nginx Apr 14, 2025 pm 12:27 PM

Le démarrage d'un serveur Nginx nécessite différentes étapes en fonction des différents systèmes d'exploitation: Système Linux / Unix: Installez le package NGINX (par exemple, en utilisant Apt-Get ou Yum). Utilisez SystemCTL pour démarrer un service NGINX (par exemple, sudo systemctl start nginx). Système Windows: téléchargez et installez les fichiers binaires Windows. Démarrer Nginx à l'aide de l'exécutable Nginx.exe (par exemple, nginx.exe -c conf \ nginx.conf). Peu importe le système d'exploitation que vous utilisez, vous pouvez accéder au serveur IP

Comment vérifier si Nginx est démarré? Comment vérifier si Nginx est démarré? Apr 14, 2025 pm 12:48 PM

Dans Linux, utilisez la commande suivante pour vérifier si Nginx est démarré: SystemCTL Status Nginx Juges Basé sur la sortie de la commande: si "Active: Active (Running)" s'affiche, Nginx est démarré. Si "Active: Inactive (Dead)" est affiché, Nginx est arrêté.

Comment démarrer Nginx dans Linux Comment démarrer Nginx dans Linux Apr 14, 2025 pm 12:51 PM

Étapes pour démarrer Nginx dans Linux: Vérifiez si Nginx est installé. Utilisez SystemCTL Start Nginx pour démarrer le service NGINX. Utilisez SystemCTL Activer Nginx pour activer le démarrage automatique de Nginx au démarrage du système. Utilisez SystemCTL Status Nginx pour vérifier que le démarrage est réussi. Visitez http: // localhost dans un navigateur Web pour afficher la page de bienvenue par défaut.

Comment créer un miroir dans Docker Comment créer un miroir dans Docker Apr 15, 2025 am 11:27 AM

Étapes pour créer une image docker: écrivez un dockerfile qui contient les instructions de construction. Créez l'image dans le terminal, en utilisant la commande docker build. Marquez l'image et attribuez des noms et des balises à l'aide de la commande docker tag.

Comment résoudre nginx403 Comment résoudre nginx403 Apr 14, 2025 am 10:33 AM

Comment corriger l'erreur interdite Nginx 403? Vérifier les autorisations de fichier ou de répertoire; 2. Vérifier le fichier .htaccess; 3. Vérifiez le fichier de configuration NGINX; 4. Redémarrer Nginx. D'autres causes possibles incluent les règles de pare-feu, les paramètres de Selinux ou les problèmes d'application.

See all articles