>  기사  >  웹 프론트엔드  >  Ajax 크로스 도메인 문제에 대한 완벽한 솔루션

Ajax 크로스 도메인 문제에 대한 완벽한 솔루션

php中世界最好的语言
php中世界最好的语言원래의
2018-04-24 16:23:152700검색

이번에는 Ajax 크로스 도메인 문제에 대한 완벽한 솔루션을 알려드리겠습니다. Ajax 크로스 도메인 문제를 해결하기 위한 주의사항은 무엇인가요? 실제 사례를 살펴보겠습니다.

오늘은 Ajax 크로스 도메인에 관한 몇 가지 문제를 기록하겠습니다. 긴급 상황에 대비해.

교차 도메인

동일 출처 정책 제한

동일 출처 정책은 한 도메인에 로드된 스크립트가 다른 도메인의 문서 속성을 가져오거나 조작하는 것을 방지합니다. 즉, 요청한 URL의 도메인은 현재 웹페이지의 도메인과 동일해야 합니다. 이는 브라우저가 서로 다른 소스의 콘텐츠를 격리하여 소스 간 작업을 방지한다는 의미입니다.

Solution

일반적으로 두 가지 일반적인 방법이 있습니다. 하나는 서버 측에서, 다른 하나는 클라이언트 관점에서 발생합니다. 둘 다 장단점이 있으며 어떤 방법을 사용할지는 구체적인 분석이 필요합니다.

  1. 서버는 응답 헤더를 설정합니다

  2. 서버 프록시

  3. 클라이언트는 스크립트 콜백 메커니즘을 사용합니다.

방법 1

Access-Control-Allow-Origin 키워드는 서버 측에 설정된 경우에만 적용됩니다. 즉,
client

xmlhttprequest.setHeaderREquest('xx','xx');
에서 사용해도 아무런 효과가 없습니다.

일반 ajax 요청

Ajax 비교차 도메인 요청의 사례 구현을 시뮬레이션해 보겠습니다.

test1.html

nbsp;html>


 <meta>
 <title>ajax 测试</title>


<input>
<p></p>
<script>
 var xhr = new XMLHttpRequest();
 var url = &#39;http://localhost/learn/ajax/test1.php&#39;;
 function crossDomainRequest() {
  document.getElementById(&#39;content&#39;).innerHTML = "<font color=&#39;red&#39;>loading...";
  // 延迟执行
  setTimeout(function () {
   if (xhr) {
    xhr.open(&#39;GEt&#39;, url, true);
    xhr.onreadystatechange = handle_response;
    xhr.send(null);
   } else {
    document.getElementById(&#39;content&#39;).innerText = "不能创建XMLHttpRequest对象";
   }
  }, 3000);
 }
 function handle_response() {
  var container = document.getElementById(&#39;content&#39;);
  if (xhr.readyState == 4) {
   if (xhr.status == 200 || xhr.status == 304) {
    container.innerHTML = xhr.responseText;
   } else {
    container.innerText = &#39;不能跨域请求&#39;;
   }
  }
 }
</script>

같은 디렉토리에 있는 test1.PHP의 내용은 다음과 같습니다.

<?php echo "It Works.";
?>

Ajax 크로스 도메인 문제에 대한 완벽한 솔루션

Cross-domain request

지금은 HTML 파일과 php 파일이 모두 아래에 있습니다 Apache 컨테이너이므로 도메인 간 요청이 없습니다. 도메인의 경우 이제 HTML 파일을 데스크탑에 놓은 다음 PHP 데이터를 다시 요청하여 이러한 "도메인 간 요청"을 생성합니다.

브라우저의 주소 표시줄 정보에 주의하세요

다시 방문하시면 아래와 같은 오류 메시지를 보실 수 있습니다.

Ajax 크로스 도메인 문제에 대한 완벽한 솔루션

이 경우 일반적인 작업은 Access-Control-Allow-Origin을 설정하는 것입니다.

형식: Access-Control-Allow-Origin: domain.com/xx/yy.*

클라이언트의 도메인 이름이나 요청의 고정 경로를 알고 있는 경우 추가 보장을 위해 와일드카드를 사용하지 않는 것이 가장 좋습니다. 보안. 확실하지 않은 경우 * 와일드카드 문자를 사용하세요.

백엔드 개발 언어가 PHP인 경우 파일 시작 부분에 이렇게 설정하면 됩니다.

header("Access-Control-Allow-Origin: *");
ASX 페이지인 경우 다음과 같이 설정합니다(Java도 비슷합니다).

Response.AddHeader("Access-Control-Allow-Origin", "*");
여기서 시간, 지금 바로 그 길을 방문해보세요.

Ajax 크로스 도메인 문제에 대한 완벽한 솔루션

Server프록시 모드

이 방법은 더 일반적으로 사용되고 널리 채택되는 방법으로 간주되어야 합니다. 에이전트라고 하기에는 좀 과한 표현이지만 사실은 그냥 메신저일 뿐입니다. 간단한 예를 들어보겠습니다.

샤오밍은 3학년 샤오홍이라는 여자아이를 좋아하지만 너무 부끄러워서 QQ와 위챗 아이디를 물어보지 못합니다. 그러다가 같은 반 여학생인 Xiaolan에게 물었습니다. 와서 그것을 얻을 수 있도록 스스로 도와주세요. 따라서 Xiaolan은 에이전트와 동일합니다. Xiao Ming이 직접 얻을 수 없는 Xiao Hong의 연락처 정보를 얻을 수 있도록 도와주세요.

이 문제를 설명하기 위해 예를 들어 보겠습니다.

직접 도메인 간 요청

지금 바로 URL을 수정하고 Ajax가 다른 웹사이트에서 직접 데이터를 요청하도록 하세요.

nbsp;html>


 <meta>
 <title>ajax 测试</title>


<input>
<p></p>
<script>
 var xhr = new XMLHttpRequest();
// var url = &#39;http://localhost/learn/ajax/test1.php&#39;;
  var url = &#39;http://api.qingyunke.com/api.php?key=free&appid=0&msg=%E5%93%92%E5%93%92&#39;;
 function crossDomainRequest() {
  document.getElementById(&#39;content&#39;).innerHTML = "<font color=&#39;red&#39;>loading...";
  // 延迟执行
  setTimeout(function () {
   if (xhr) {
    xhr.open(&#39;GEt&#39;, url, true);
    xhr.onreadystatechange = handle_response;
    xhr.send(null);
   } else {
    document.getElementById(&#39;content&#39;).innerText = "不能创建XMLHttpRequest对象";
   }
  }, 3000);
 }
 function handle_response() {
  var container = document.getElementById(&#39;content&#39;);
  if (xhr.readyState == 4) {
   if (xhr.status == 200 || xhr.status == 304) {
    container.innerHTML = xhr.responseText;
   } else {
    container.innerText = &#39;不能跨域请求&#39;;
   }
  }
 }
</script>

결과는 다음과 같습니다.

Ajax 크로스 도메인 문제에 대한 완벽한 솔루션

프록시 모드 활성화

지금 HTML 페이지에서는 여전히 자체 인터페이스를 사용합니다.

url = 'http://localhost/learn/ajax/test1.php';

具体如下:

nbsp;html>


 <meta>
 <title>ajax 测试</title>


<input>
<p></p>
<script>
 var xhr = new XMLHttpRequest();
 var url = &#39;http://localhost/learn/ajax/test1.php&#39;;
//  var url = &#39;http://api.qingyunke.com/api.php?key=free&appid=0&msg=%E5%93%92%E5%93%92&#39;;
 function crossDomainRequest() {
  document.getElementById(&#39;content&#39;).innerHTML = "<font color=&#39;red&#39;>loading...";
  // 延迟执行
  setTimeout(function () {
   if (xhr) {
    xhr.open(&#39;GEt&#39;, url, true);
    xhr.onreadystatechange = handle_response;
    xhr.send(null);
   } else {
    document.getElementById(&#39;content&#39;).innerText = "不能创建XMLHttpRequest对象";
   }
  }, 3000);
 }
 function handle_response() {
  var container = document.getElementById(&#39;content&#39;);
  if (xhr.readyState == 4) {
   if (xhr.status == 200 || xhr.status == 304) {
    container.innerHTML = xhr.responseText;
   } else {
    container.innerText = &#39;不能跨域请求&#39;;
   }
  }
 }
</script>

然后对应的test1.php应该帮助我们实现数据请求这个过程,把“小红的联系方式”要到手,并返回给“小明”。

<?php $url = &#39;http://api.qingyunke.com/api.php?key=free&appid=0&msg=hello%20world.&#39;;
$result = file_get_contents($url);
echo $result;
?>

下面看下代码执行的结果。

Ajax 크로스 도메인 문제에 대한 완벽한 솔루션

jsonp方式

JSONP(JSON with Padding) 灵感其实源于在HTML页面中script标签内容的加载,对于script的src属性对应的内容,浏览器总是会对其进行加载。于是:

克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。

实现的思路就是:

在服务器端组装出客户端预置好的json数据,通过回调的方式传回给客户端。

原生实现

nbsp;html>


 <meta>
 <title>ajax 测试</title>
 <script></script>


<input>
<input>
<p></p>
<script>
function jsonpcallback(result) {
 for(var i in result) {
  alert(i+":"+result[i]);
 }
 }
 var JSONP = document.createElement("script");
 JSONP.type=&#39;text/javascript&#39;;
 JSONP.src=&#39;http://localhost/learn/ajax/test1.php?callback=jsonpcallback&#39;;
 document.getElementsByTagName(&#39;head&#39;)[0].appendChild(JSONP);
</script>

服务器端test1.php内容如下:

<?php $arr = [1,2,3,4,5,6];
$result = json_encode($arr);
echo "jsonpcallback(".$result.")";
?>

需要注意的是最后组装的返回值内容。

来看下最终的代码执行效果。

Ajax 크로스 도메인 문제에 대한 완벽한 솔루션

JQuery方式实现

采用原生的JavaScript需要处理的事情还是蛮多的,下面为了简化操作,决定采用jQuery来代替一下。

nbsp;html>


 <meta>
 <title>ajax 测试</title>
 <script></script>


<input>
<input>
<p></p>
<script>
 function later_action(msg) {
  var element = $("<p><font color=&#39;green&#39;>"+msg+"<br />");
  $("#content").append(element);
 }
 $("#btn").click(function(){
  // alert($("#talk").val());
  $.ajax({
  url: &#39;http://localhost/learn/ajax/test1.php&#39;,
  method: &#39;post&#39;,
  dataType: &#39;jsonp&#39;,
  data: {"talk": $("#talk").val()},
  jsonp: &#39;callback&#39;,
  success: function(callback){
   console.log(callback.content);
   later_action(callback.content);
  },
  error: function(err){
   console.log(JSON.stringify(err));
  },
 });
 });
</script>

相应的,test1.php为了配合客户端聊天的需求,也稍微做了点改变。

<?php $requestparam = isset($_GET[&#39;callback&#39;])?$_GET[&#39;callback&#39;]:&#39;callback&#39;;
// 青云志聊天机器人接口: http://api.qingyunke.com/api.php?key=free&appid=0&msg=hello
// 接收来自客户端的请求内容
$talk = $_REQUEST[&#39;talk&#39;];
$result = file_get_contents("http://api.qingyunke.com/api.php?key=free&appid=0&msg=$talk");
// 拼接一些字符串
echo $requestparam . "($result)";
?>

最后来查看一下跨域的效果吧。

JSONP 跨域实现聊天应用

总结

至此,关于简单的ajax跨域问题,就算是解决的差不多了。对我个人而言,对于这三种方式有一点点自己的看法。

  1. 服务器设置Access-Control-Allow-Origin的方式适合信用度高的小型应用或者个人应用。

  2. 代理模式则比较适合大型应用的处理。但是需要一个统一的规范,这样管理和维护起来都会比较方便。

  3. JSONP方式感觉还是比较鸡肋的(有可能是我经验还不足,没认识到这个方式的优点吧(⊙﹏⊙)b)。自己玩玩知道有这么个东西好了。维护起来实在是优点麻烦。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

详细解析JS中Ajax的使用技巧

JQuery调用Ajax加载图片

위 내용은 Ajax 크로스 도메인 문제에 대한 완벽한 솔루션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.