Maison >interface Web >js tutoriel >Comment résoudre le problème inter-domaines Ajax

Comment résoudre le problème inter-domaines Ajax

coldplay.xixi
coldplay.xixioriginal
2020-10-29 09:25:272313parcourir

Solution au problème inter-domaines ajax : 1. Ajoutez un en-tête à l'en-tête de réponse pour autoriser l'accès ; 2. jsonp ne prend en charge que les requêtes d'obtention mais pas les requêtes de publication ; 3. Transfert interne de httpClient 4. Utilisez nginx pour construire ; une passerelle d'interface au niveau de l'entreprise.

Comment résoudre le problème inter-domaines Ajax

Recommandations d'apprentissage gratuites associées : ajax (Vidéo )

Solution au problème inter-domaines ajax :

Solution 1 : Ajouter un en-tête à l'en-tête de réponse pour autoriser l'accès

Partage de ressources entre origines croisées (CORS) Partage de ressources entre origines croisées

Le fondement de sécurité de cette solution d'accès entre domaines est basé sur "JavaScript ne peut pas contrôler cet en-tête HTTP"

Il est nécessaire d'autoriser ou non l'accès entre domaines via l'en-tête HTTP renvoyé par le domaine cible.

response.addHeader(‘Access-Control-Allow-Origin:*’);//允许所有来源访问 
response.addHeader(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式

Solution 2 : jsonp ne prend en charge que les requêtes d'obtention mais pas de publication

Utilisation : ①Changez le type de données en jsonp ②jsonp : "jsonpCallback"— — —La valeur réelle envoyée au backend est http://a.a.com/a/FromServlet?userName=644064&jsonpCallback=jQueryxxx ③Le backend obtient le jsonpCallback dans la requête get ④Construire la structure de rappel

$.ajax({
type : "GET",
async : false,
url : "http://a.a.com/a/FromServlet?userName=644064",
dataType : "jsonp",//数据类型为jsonp  
jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数
success : function(data) {
alert(data["userName"]);
},
error : function() {
alert('fail');
}
});
 
//后端
        String jsonpCallback = request.getParameter("jsonpCallback");
//构造回调函数格式jsonpCallback(数据)
resp.getWriter().println(jsonpCallback+"("+jsonObject.toJSONString()+")");

Implémentation JSONP Principe

Dans le cadre de la politique de même origine, les pages sous un certain serveur ne peuvent pas obtenir de données en dehors du serveur, c'est-à-dire que l'ajax général ne peut pas faire de requêtes inter-domaines. Cependant, les balises telles que img, iframe et script sont des exceptions. Ces balises peuvent demander des données sur d'autres serveurs via l'attribut src. Grâce à la politique d'ouverture de la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a, nous pouvons demander des données sur plusieurs domaines. Bien entendu, cela nécessite la coopération du serveur. Le cœur d'ajax dans Jquery est d'obtenir du contenu autre que cette page via XmlHttpRequest, tandis que le cœur de jsonp est d'ajouter dynamiquement la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a

Lorsque nous demandons normalement une donnée JSON, le serveur renvoie une chaîne de données de type JSON, et lorsque nous utilisons le mode JSONP pour demander des données, le serveur renvoie un code JavaScript exécutable. Étant donné que le principe inter-domaines de jsonp est de charger dynamiquement le src de 3f1c4e4b6b16bbbd69b2ee476dc4f83a, nous ne pouvons transmettre les paramètres que via l'URL, donc le type de jsonp ne peut être obtenu !

Exemple :

$.ajax({
    url: 'http://192.168.10.46/demo/test.jsp',        //不同的域
    type: 'GET',                                                        // jsonp模式只有GET 是合法的
    data: {
        'action': 'aaron'
    },
    dataType: 'jsonp',                                              // 数据类型
    jsonp: 'jsonpCallback',                                     // 指定回调函数名,与服务器端接收的一致,并回传回来
})

En fait, jquery le convertira en interne en aron

Puis charger dynamiquement

<script type="text/javascript"src="http://192.168.10.46/demo/test.jsp?jsonpCallback= jQuery202003573935762227615_1402643146875&action=aaron"></script>

puis le backend exécutera jsonpCallback (pass paramètres) et envoyer les données sous forme de paramètres réels.

L'ensemble du processus d'utilisation du mode JSONP pour demander des données : le client envoie une requête et spécifie un nom de fonction exécutable (ici, jQuery effectue le processus d'encapsulation et génère automatiquement une fonction de rappel pour vous et extrait les données pour le méthode d'attribut success à appeler, au lieu de passer un handle de rappel), le serveur accepte le nom de la fonction jsonpCallback, puis envoie les données sous la forme de paramètres réels

(dans jquery In le code source, jsonp est implémenté en ajoutant dynamiquement la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a pour appeler le script js fourni par le serveur. jquery chargera une fonction globale dans l'objet window. Lorsque le code 3f1c4e4b6b16bbbd69b2ee476dc4f83a être exécuté. 3f1c4e4b6b16bbbd69b2ee476dc4f83a sera supprimé dans le même temps, jquery a également optimisé les requêtes non inter-domaines. Si la requête est sous le même nom de domaine, elle fonctionnera comme une requête Ajax normale)

Solution 3 : Redirection interne httpClient

Le principe de mise en œuvre est très simple Si vous souhaitez accéder au site A via Ajax dans le site B pour obtenir des résultats, là. sera bien sûr un problème inter-domaine ajax, mais il n'y a pas de problème inter-domaine lors de l'accès au site B pour obtenir des résultats sur le site B. Cette méthode consiste en fait à accéder au HttpClient du site B avec ajax dans le site B, puis transmettre la demande via HttpClient pour obtenir les résultats des données du site A. Cependant, cette méthode génère deux requêtes, ce qui est inefficace. Cependant, les requêtes internes ne peuvent pas être analysées par les outils de capture de paquets et sont sécurisées.

$.ajax({
type : "GET",
async : false,
url : "http://b.b.com:8080/B/FromAjaxservlet?userName=644064",
dataType : "json",
success : function(data) {
alert(data["userName"]);
},
error : function() {
alert(&#39;fail&#39;);
}
});
 
@WebServlet("/FromAjaxservlet")
public class FromAjaxservlet extends HttpServlet{
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//创建默认连接
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建HttpGet对象,处理get请求,转发到A站点
HttpGet httpGet = new HttpGet("http://a.a.com:8080/A/FromServlet?userName="+req.getParameter("userName")); 
                        //执行
CloseableHttpResponse response = httpClient.execute(httpGet);
int code = response.getStatusLine().getStatusCode();
//获取状态
System.out.println("http请求结果为:"+code);
if(code == 200){
                                //获取A站点返回的结果
String result = EntityUtils.toString(response.getEntity());
System.out.println(result);
                                //把结果返回给B站点
resp.getWriter().print(result);
}
response.close();
httpClient.close();
} catch (Exception e) {
}
}
}

Solution 4 : Utilisez nginx pour créer une passerelle d'interface au niveau de l'entreprise

www.a.a.com ne peut pas demander directement le contenu de www. b.b.com , vous pouvez utiliser nginx pour différencier en fonction du même nom de domaine mais de noms de projets différents. Qu'est-ce que ça veut dire? C'est peut-être un peu abstrait. Supposons que le nom de domaine de notre entreprise est www.nginxtest.com

Lorsque nous devons accéder à www.a.a.com via www.nginxtest.com/A, et le transmettre à www.a.a.com

via nginx Nous devons accéder à www.b.b.com via www.nginxtest.com/B, et le transmettre à www.a.a.com via nginx

Lorsque nous accédons au nom de domaine de l'entreprise, il s'agit de "même source", mais le nom du projet est différent, le rôle du nom du projet à l'heure actuelle est simplement de distinguer et de faciliter le transfert. Si vous ne comprenez toujours pas, jetez un oeil à comment je l'ai configuré :

server {
        listen       80;
        server_name  www.nginxtest.com;
        location /A {
    proxy_pass  http://a.a.com:81;
index  index.html index.htm;
        }
location /B {
    proxy_pass  http://b.b.com:81;
index  index.html index.htm;
        }
    }

我们访问以www.nginxtest.com开头且端口为80的网址,nginx将会进行拦截匹配,若项目名为A,则分发到a.a.com:81。实际上就是通过"同源"的域名,不同的项目名进行区分,通过nginx拦截匹配,转发到对应的网址。整个过程,两次请求,第一次请求nginx服务器,第二次nginx服务器通过拦截匹配分发到对应的网址。

相关免费学习推荐:javascript(视频)

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:
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