Partage de technologie

Bien comprendre le cross-domain front-end

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

 

Table des matières

1Politique de même origine du navigateur

1.1 Aperçu de la politique de même origine

1.2 Qu'est-ce que l'origine ?

2. Quelles sont les restrictions sur les transactions inter-domaines ?

2.1 Restreindre l'accès au DOM

2.2 Restreindre l'accès aux cookies

2.3 Limiter Ajax pour obtenir des données

3 points à noter

4CORS résout les problèmes inter-domaines Ajax

4.1Aperçu du CORS

4.2CORS résout des requêtes inter-domaines simples

4.3 Demandes simples et demandes complexes

4.4CORS résout les requêtes inter-domaines complexes

4.5 Utilisez la bibliothèque cors pour terminer rapidement la configuration

5JSONP résout les problèmes inter-domaines

6Configurer le proxy pour résoudre les problèmes inter-domaines

6.1 Configurez vous-même le serveur proxy

6.2 Utiliser Nginx pour créer un serveur proxy

6.3 Construire un serveur à l'aide d'un échafaudage


Adresse du code git clone https://gitee.com/childe-jia/cross-domain-test.git

1Politique de même origine du navigateur

1.1 Aperçu de la politique de même origine


La politique de même origine est une politique que les navigateurs suivent pour garantir la sécurité des ressources. Cette politique impose certaines restrictions sur l'accès aux ressources.
Description de la politique de même origine du W3C :Politique de même origine

1.2 Qu'est-ce que l'origine ?


1 composants sources

image.png


2Dans le tableau ci-dessous, seules les deux sources de la dernière ligne ont la même origine.

Source 1

Source 2

Est-ce homologue ?

http://www.xyz.com/home

https://www.xyz.com/home

⛔Non homogène️

http://www.xyz.com/home

http://mail.xyz.com/home

⛔Non homogène

http://www.xyz.com:8080/home

http://www.xyz.com:8090/home

⛔Non homogène

http://www.xyz.com:8080/home

http://www.xyz.com:8080/search

✅Même origine︎

 

3 demande d'origine

image.png


4 Demande non originale

image.png


5 Résumé : Si la « source » est incohérente avec la « source cible », cela signifie « non-source », également appelé « hétérosource » ou « cross-domain »

2. Quelles sont les restrictions sur les transactions inter-domaines ?


Par exemple, s'il y a deux sources : "Source A" et "Source B", qui ne sont pas de "même origine", alors le navigateur aura les restrictions suivantes :

2.1 Restreindre l'accès au DOM

Le script de "Source A" ne peut pas accéder au DOM de "Source B".

  1. <!-- <iframe id="framePage" src="./demo.html"></iframe> -->
  2. <iframe id="framePage" src="https://www.baidu.com"></iframe>
  3. <script type="text/javascript" >
  4. function showDOM(){
  5. const framePage = document.getElementById('framePage')
  6. console.log(framePage.contentWindow.document) //同源的可以获取,非同源的无法获取
  7. }
  8. </script>

2.2 Restreindre l'accès aux cookies

"Source A" ne peut pas accéder au cookie de "Source B"

  1. <iframe id="baidu" src="http://www.baidu.com" width="500" height="300"></iframe>
  2. <script type="text/javascript" >
  3. // 访问的是当前源的cookie,并不是baidu的cookie
  4. console.log(document.cookie)
  5. </script>

2.3 Limiter Ajax pour obtenir des données

La « Source A » peut envoyer des requêtes à la « Source B », mais ne peut pas obtenir les données de réponse de la « Source B ».

  1. const url = 'https://www.toutiao.com/hot-event/hot-board/?origin=toutiao_pc'
  2. let result = await fetch(url)
  3. let data = await result.json();
  4. console.log(data)

Remarque : Parmi les restrictions ci-dessus, la restriction du navigateur sur l'acquisition de données Ajax a le plus grand impact et est souvent rencontrée dans le développement réel.

3 points à noter

  • 1Les restrictions entre domaines n'existent que du côté du navigateur et il n'y a aucune restriction entre domaines du côté du serveur.
  • 2 Même si elles sont inter-domaines, les requêtes Ajax peuvent être émises normalement, mais les données de réponse ne seront pas transmises au développeur.
  • 3<link> , <script>、<img>...... 这些标签发出的请求也可能跨域,只不过浏览器对标签跨域不做严格限制,对开发几乎无影响

image.png

4CORS résout les problèmes inter-domaines Ajax

4.1Aperçu du CORS

Le nom complet de CORS : Cross-Origin Resource Sharing (Cross-Origin Resource Sharing) est un ensemble de spécifications utilisées pour contrôler la vérification du navigateur des requêtes inter-domaines. Le serveur suit la spécification CORS et ajoute des en-têtes de réponse spécifiques pour contrôler la vérification du navigateur. Les règles générales sont les suivantes :
●Le serveur rejette explicitement les requêtes inter-domaines, ou ne l'indique pas, et le navigateur échoue à la vérification.
●Le serveur indique clairement que les requêtes inter-domaines sont autorisées et la vérification du navigateur réussit.
Remarque : L'utilisation de CORS pour résoudre des problèmes inter-domaines est la méthode la plus orthodoxe et nécessite que le serveur soit « propre ».


4.2CORS résout des requêtes inter-domaines simples

L'idée générale : lorsque le serveur répond, il exprime clairement qu'une certaine source est autorisée à lancer des requêtes inter-domaines en ajoutant l'en-tête de réponse Access-Control-Allow-Origin, puis le navigateur le transmet directement lors de la vérification.

image.png

Code de base côté serveur (prenons le framework Express comme exemple) :

  1. // 处理跨域中间件
  2. function corsMiddleWare(req,res,next){
  3. // 允许 http://127.0.0.1:5500 这个源发起跨域请求
  4. // res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:5500')
  5. // 允许所有源发起跨域请求
  6. res.setHeader('Access-Control-Allow-Origin','*')
  7. next()
  8. }
  9. // 配置路由并使用中间件
  10. app.get('/',corsMiddleWare,(req,res)=>{
  11. res.send('hello!')
  12. })

4.3 Demandes simples et demandes complexes

CORS divise les demandes en deux catégories : ① les demandes simples et ② les demandes complexes.

simple demande

Demande complexe

✅La méthode de requête (méthode) est : GET, HEAD, POST

1 est soit une requête simple, soit une requête complexe.
2 Les demandes complexes enverront automatiquement des demandes de contrôle en amont.

✅Les champs d'en-tête de la requête doivent être conformes"Spécification de sécurité CORS"
Note courte : Tant que l'en-tête de la requête n'est pas modifié manuellement, il peut généralement être conforme à cette spécification.

✅La valeur Content-Type de l'en-tête de requête ne peut être que les trois suivantes :
●texte/brut
● données multiparties/formulaires
●application/x-www-formulaire-urlencode

Concernant les demandes de contrôle en amont :

  • 1Délai d'envoi : la demande de contrôle en amont est envoyée avant la demande inter-domaines proprement dite et est automatiquement lancée par le navigateur.
  • 2 Fonction principale : utilisée pour confirmer auprès du serveur s'il faut autoriser la prochaine requête inter-domaines.
  • 3Processus de base : lancez d'abord une requête OPTIONS. Si elle réussit la vérification préalable, continuez à lancer la requête inter-domaines réelle.
  • 4 Contenu de l'en-tête de requête : une requête de contrôle en amont OPTIONS contient généralement les en-têtes de requête suivants :

En-tête de requête

signification

Origine

La source de la demande

Méthode de demande de contrôle d'accès

La méthode HTTP réellement demandée

En-têtes de demande de contrôle d'accès

En-têtes personnalisés utilisés dans la demande réelle (le cas échéant)

4.4CORS résout les requêtes inter-domaines complexes

1 Première étape : le serveur transmet d'abord la requête de contrôle en amont du navigateur. Le serveur doit renvoyer l'en-tête de réponse suivant :

en-tête de réponse

signification

Contrôle d'accès-Autoriser-Origine

sources autorisées

Méthodes d'autorisation de contrôle d'accès

méthodes autorisées

En-têtes d'autorisation de contrôle d'accès

En-têtes personnalisés autorisés

Contrôle d'accès - Âge maximum

Temps de mise en cache des résultats pour les demandes de contrôle en amont (facultatif)

image.png

2 Étape 2 : Gérer la requête inter-domaine réelle (de la même manière que vous gérez les requêtes inter-domaines simples)

image.png

Code de base du serveur :

  1. // 处理预检请求
  2. app.options('/students', (req, res) => {
  3. // 设置允许的跨域请求源
  4. res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
  5. // 设置允许的请求方法
  6. res.setHeader('Access-Control-Allow-Methods', 'GET')
  7. // 设置允许的请求头
  8. res.setHeader('Access-Control-Allow-Headers', 'school')
  9. // 设置预检请求的缓存时间(可选)
  10. res.setHeader('Access-Control-Max-Age', 7200)
  11. // 发送响应
  12. res.send()
  13. })
  14. // 处理实际请求
  15. app.get('/students', (req, res) => {
  16. // 设置允许的跨域请求源
  17. res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
  18. // 随便设置一个自定义响应头
  19. res.setHeader('abc',123)
  20. // 设置允许暴露给客户端的响应头
  21. res.setHeader('Access-Control-Expose-Headers', 'abc')
  22. // 打印请求日志
  23. console.log('有人请求/students了')
  24. // 发送响应数据
  25. res.send(students)
  26. })

4.5 Utilisez la bibliothèque cors pour terminer rapidement la configuration

Dans la configuration ci-dessus, vous devez configurer vous-même l'en-tête de réponse ou encapsuler manuellement le middleware. Avec la bibliothèque cors, vous pouvez terminer la configuration plus facilement.

●Installer les cors

npm i cors

●Corps de configuration simples

app.use(cors())

●Configurer complètement les cors

  1. // cors中间件配置
  2. const corsOptions = {
  3. origin: 'http://127.0.0.1:5500', // 允许的源
  4. methods: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'], // 允许的方法
  5. allowedHeaders: ['school'], // 允许的自定义头
  6. exposedHeaders: ['abc'], // 要暴露的响应头
  7. optionsSuccessStatus: 200 // 预检请求成功的状态码
  8. };
  9. app.use(cors(corsOptions)); // 使用cors中间件

Par défaut, js ne peut pas accéder à l'en-tête de réponse défini par le backend et doit être exposé par le backend.

5JSONP résout les problèmes inter-domaines

1Présentation de JSONP : utilisations de JSONP<script>标签可以跨域加载脚本,且不受严格限制的特性,可以说是程序员智慧的结晶,早期一些浏览器不支持 CORS 的时,可以靠 JSONP 解决跨域。


2Processus de base :

  • ○Première étape : le client crée un<script>标签,并将其src属性设置为包含跨域请求的 URL,同时准备一个回调函数,这个回调函数用于处理返回的数据。
  • ○Étape 2 : Après avoir reçu la requête, le serveur encapsule les données dans la fonction de rappel et les renvoie.
  • ○Étape 3 : la fonction de rappel du client est appelée et les données sont transmises à la fonction de rappel sous forme de paramètres.

3Illustration :

image.png

4 exemples de code :

  1. <button onclick="getTeachers()">获取数据</button>
  2. <script type="text/javascript" >
  3. function callback(data){
  4. console.log(data)
  5. }
  6. function getTeachers(url){
  7. // 创建script元素
  8. const script = document.createElement('script')
  9. // 指定script的src属性
  10. script.src= 'http://127.0.0.1:8081/teachers'
  11. // 将script元素添加到body中触发脚本加载
  12. document.body.appendChild(script)
  13. // script标签加载完毕后移除该标签
  14. script.onload = ()=>{
  15. script.remove()
  16. }
  17. }
  18. </script>

Jsonp encapsulé par 5jQuery

?callback=?' est un format fixe et sera automatiquement analysé

  1. $.getJSON('http://127.0.0.1:8081/teachers?callback=?',(data)=>{
  2. console.log(data)
  3. })

6Configurer le proxy pour résoudre les problèmes inter-domaines

6.1 Configurez vous-même le serveur proxy

Il n'y a pas de problèmes inter-domaines entre les serveurs. Vous devez utiliser express pour démarrer les ressources statiques afin de vous assurer que votre serveur et votre page sont sous la même origine.

  1. // 启动静态资源 让服务器跟页面同一个源
  2. app.use(express.static("./public"));

Configurer le proxy avec http-proxy-middleware

  1. const { createProxyMiddleware } = require('http-proxy-middleware');
  2. app.use('/api',createProxyMiddleware({
  3. target:'https://www.toutiao.com',
  4. changeOrigin:true,
  5. pathRewrite:{
  6. '^/api':''
  7. }

 

avantage:

  • Fonctions riches : http-proxy-middleware offre une multitude d'options de configuration pour répondre à divers besoins de proxy.
  • Configuration flexible de plusieurs proxys : plusieurs serveurs proxy peuvent être configurés, correspondant à différents chemins d'interface.
  • Peut intercepter les requêtes : les requêtes peuvent être interceptées et modifiées via des fonctions de traitement personnalisées.

défaut:

  • La configuration est relativement complexe : vous devez comprendre les règles de configuration et les paramètres de la bibliothèque http-proxy-middleware.
  • Ne convient pas aux environnements de production : http-proxy-middleware est principalement utilisé dans les environnements de développement et n'est pas adapté aux environnements de production.

scènes à utiliser :

  • Convient aux projets front-end utilisant n’importe quel outil de construction et fonctionne avec n’importe quel serveur de développement.
  • Convient aux scénarios dans lesquels plusieurs serveurs proxy doivent être configurés de manière flexible.
  • Convient aux scénarios dans lesquels les demandes doivent être interceptées et modifiées.

6.2 Utiliser Nginx pour créer un serveur proxy

L'idée générale : laisser nginx jouer deux rôles, à la fois en tant que serveur de contenu statique et en tant que serveur proxy.

Modifiez la configuration de nginx comme suit. Notez que le répertoire racine de nginx n'est de préférence pas le lecteur C.

  1. # 配置nginx根目录
  2. location / {
  3. root D:dist;
  4. index index.html index.htm;
  5. }
  6. # 配置代理
  7. location /dev/ {
  8. # 设置代理目标
  9. proxy_pass http://sph-h5-api.atguigu.cn/;
  10. }

2 Modifiez le projet frontal afin que toutes les requêtes soient transmises à /dev, puis reconditionnées

  1. const request = axios.create({
  2. baseURL:'/dev',
  3. timeout:10000
  4. })

Accédez ensuite directement au serveur nginx. Par exemple, si nginx s'exécute sur le port 8099, accédez.

http://localhost:8099

Ensuite, vous rencontrerez le problème d'actualisation 404, ajoutez la configuration nginx pour le résoudre

  1. # 配置nginx根目录
  2. location / {
  3. root D:dist;
  4. index index.html index.htm;
  5. try_files $uri $uri/ /index.html; # 解决刷新404
  6. }
  7. # 配置代理
  8. location /dev/ {
  9. # 设置代理目标
  10. proxy_pass http://sph-h5-api.atguigu.cn/;
  11. }

L'ajout de ces deux "/" élimine le développement

6.3 Construire un serveur à l'aide d'un échafaudage

1. Utilisez le fichier vue.config.js pour configurer le proxy :

Créez un fichier vue.config.js dans le répertoire racine du projet Vue et ajoutez le code suivant :

  1. module.exports = {
  2. devServer: {
  3. proxy: {
  4. '/api': {
  5. target: 'http://api.example.com',
  6. changeOrigin: true,
  7. pathRewrite: {
  8. '^/api': ''
  9. }
  10. }
  11. }
  12. }
  13. }

Dans le code ci-dessus, nous utilisonsdevServer Éléments de configuration pour configurer le serveur proxy.dansproxyLes propriétés permettent de configurer les règles du proxy,/apiIndique le chemin d'accès de l'interface qui nécessite un proxy.targetL'attribut représente l'adresse du serveur cible du proxy,changeOriginL'attribut indique s'il faut modifier l'adresse source de la demande.pathRewritePropriété utilisée pour remplacer le chemin demandé.

avantage:

  • Configuration simple : en utilisant la configuration proxy de webpack-dev-server, il vous suffit d'effectuer une configuration simple dans le fichier de configuration webpack.
  • Fonctionnalité complète : webpack-dev-server offre une multitude d'options de configuration pour répondre à la plupart des besoins de proxy.
  • Peut intercepter les requêtes : les requêtes peuvent être interceptées et modifiées via des fonctions de traitement personnalisées.

défaut:

  • Le serveur doit être redémarré : une fois la configuration modifiée, webpack-dev-server doit être redémarré pour prendre effet.
  • Ne convient pas aux environnements de production : webpack-dev-server est principalement utilisé dans les environnements de développement et n'est pas adapté aux environnements de production.

scènes à utiliser :

  • Il convient aux projets frontaux construits à l'aide de webpack et au démarrage du serveur de développement via webpack-dev-server.
  • Il convient aux scénarios qui nécessitent une configuration de proxy simple et ne nécessitent pas de modifier fréquemment la configuration du proxy.