>  기사  >  웹 프론트엔드  >  JS에서 구현한 Ajax 및 Same Origin 전략에 대한 자세한 설명

JS에서 구현한 Ajax 및 Same Origin 전략에 대한 자세한 설명

小云云
小云云원래의
2018-05-30 11:59:111953검색

JS와 Ajax는 모두 우리 프로그램에 필수적이며 밀접하게 연결되어 있습니다. 이 기사에서는 JS에서 구현된 ajax 및 동일 출처 전략의 예를 주로 공유합니다. 이는 좋은 참고 가치가 있으며 모든 사람에게 도움이 되기를 바랍니다.

1. jQuery로 구현된 ajax 검토

먼저 ajax의 장점과 단점에 대해 이야기해 보겠습니다.

장점:

AJAX는 Javascript 기술을 사용하여 서버에 비동기 요청을 보냅니다.

AJAX 전체 페이지를 새로 고칠 필요가 없습니다.

서버 응답 콘텐츠가 더 이상 전체 페이지가 아니라 페이지의 일부이기 때문에 AJAX 성능이 높습니다.

ajquery

index로 구현됩니다. .html

<!DOCTYPE html>

<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <script src="{% static &#39;JS/jquery-3.1.1.js&#39; %}"></script>
</head>
<body>

<button class="send_Ajax">send_Ajax</button>

<script>
 //$.ajax的两种使用方式:

 //$.ajax(settings);
 //$.ajax(url,[settings]);


 $(".send_Ajax").click(function(){

  $.ajax({
  url:"/handle_Ajax/",
  type:"POST",
  data:{username:"Yuan",password:123},

  success:function(data){
   alert(data)
  },

   //=================== error============

  error: function (jqXHR, textStatus, err) {

   // jqXHR: jQuery增强的xhr
   // textStatus: 请求完成状态
   // err: 底层通过throw抛出的异常对象,值与错误类型有关
   console.log(arguments);
   },

   //=================== complete============

  complete: function (jqXHR, textStatus) {
   // jqXHR: jQuery增强的xhr
   // textStatus: 请求完成状态 success | error
   console.log(&#39;statusCode: %d, statusText: %s&#39;, jqXHR.status, jqXHR.statusText);
   console.log(&#39;textStatus: %s&#39;, textStatus);
  },

  //=================== statusCode============
  statusCode: {
   &#39;403&#39;: function (jqXHR, textStatus, err) {
   console.log(arguments); //注意:后端模拟errror方式:HttpResponse.status_code=500
   },

   &#39;400&#39;: function () {
   }
  }

  })

 })

</script>
</body>
</html>

Views.py

import json,time
 
def index(request):
 
 return render(request,"index.html")
 
def handle_Ajax(request):
 
 username=request.POST.get("username")
 password=request.POST.get("password")
 
 print(username,password)
 time.sleep(10)
 
 return HttpResponse(json.dumps("Error Data!"))

$.ajax 매개변수

요청 매개변수

######################------------data---------################

  data: 当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式
    (urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。

    function testData() {
    $.ajax("/test",{  //此时的data是一个json形式的对象
     data:{
     a:1,
     b:2
     }
    });     //?a=1&b=2
######################------------processData---------################

processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false,
    那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString()
    ,最后得到一个[object,Object]形式的结果。
   
######################------------contentType---------################

contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
    用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,
    比如contentType:"application/json",即向服务器发送一个json字符串:
    $.ajax("/ajax_get",{
    
     data:JSON.stringify({
      a:22,
      b:33
     }),
     contentType:"application/json",
     type:"POST",
    
    });       //{a: 22, b: 33}

    注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象

    views.py: json.loads(request.body.decode("utf8"))


######################------------traditional---------################

traditional:一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]},
    traditional为false会对数据进行深层次迭代;

응답 매개변수

/*

dataType: 预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。
   默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;
   比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容
   进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式
   的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用
   data Type。
   dataType的可用值:html|xml|json|text|script
   见下dataType实例

*/

간단한 연습: 두 숫자의 합을 계산합니다.

방법 1: contentType이 지정되지 않았습니다. 여기: 기본값은 urlencode method입니다

index.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width">
 <title>Title</title>
 <script src="/static/jquery-3.2.1.min.js"></script>
 <script src="http://apps.bdimg.com/libs/jquery.cookie/1.4.1/jquery.cookie.js"></script>
</head>
<body>
<h1>计算两个数的和,测试ajax</h1>
<input type="text" class="num1">+<input type="text" class="num2">=<input type="text" class="ret">
<button class="send_ajax">sendajax</button>

<script>
 $(".send_ajax").click(function () {
   $.ajax({
   url:"/sendAjax/",
   type:"post",
   headers:{"X-CSRFToken":$.cookie(&#39;csrftoken&#39;)}, 
   data:{
    num1:$(".num1").val(),
    num2:$(".num2").val(),
   },
   success:function (data) {
    alert(data);
    $(".ret").val(data)
   }
  })
 })

</script>
</body>
</html>

views.py

def index(request):
 return render(request,"index.html")

def sendAjax(request):
 print(request.POST)
 print(request.GET)
 print(request.body) 
 num1 = request.POST.get("num1")
 num2 = request.POST.get("num2")
 ret = float(num1)+float(num2)
 return HttpResponse(ret)

방법 2: 보낼 json 데이터로 conentType을 지정하세요:

index2.html

<script>
 $(".send_ajax").click(function () {
   $.ajax({
   url:"/sendAjax/",
   type:"post",
   headers:{"X-CSRFToken":$.cookie(&#39;csrftoken&#39;)}, //如果是json发送的时候要用headers方式解决forbidden的问题
   data:JSON.stringify({
    num1:$(".num1").val(),
    num2:$(".num2").val()
   }),
   contentType:"application/json", //客户端告诉浏览器是以json的格式发的数据,所以的吧发送的数据转成json字符串的形式发送
   success:function (data) {
    alert(data);
    $(".ret").val(data)
   }
  })
 })

</script>

views.py

def sendAjax(request):
 import json
 print(request.POST) #<QueryDict: {}>
 print(request.GET) #<QueryDict: {}>
 print(request.body) #b&#39;{"num1":"2","num2":"2"}&#39; 注意这时的数据不再POST和GET里,而在body中
 print(type(request.body.decode("utf8"))) # <class &#39;str&#39;>
 # 所以取值的时候得去body中取值,首先得反序列化一下
 data = request.body.decode("utf8")
 data = json.loads(data)
 num1= data.get("num1")
 num2 =data.get("num2")
 ret = float(num1)+float(num2)
 return HttpResponse(ret)


2. JS 구현 ajax

1. AJAX 코어(XMLHttpRequest)

실제로 AJAX는 Javascript에 XMLHttpRequest 객체를 추가합니다. 모든 비동기 상호작용은 XMLHttpServlet 객체를 사용하여 수행됩니다. 즉, 우리는 Javascript의 새로운 객체만 배우면 됩니다.

var xmlHttp = new XMLHttpRequest(); (대부분의 브라우저는 DOM2 사양을 지원합니다.)

각 브라우저의 XMLHttpRequest 지원도 다르다는 점에 유의하세요! 브라우저 호환성 문제를 해결하기 위해 XMLHttpRequest 객체를 생성하는 방법이 제공됩니다:

function createXMLHttpRequest() {
    var xmlHttp;
    // 适用于大多数浏览器,以及IE7和IE更高版本
    try{
      xmlHttp = new XMLHttpRequest();
    } catch (e) {
      // 适用于IE6
      try {
        xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
        // 适用于IE5.5,以及IE更早版本
        try{
          xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e){}
      }
    }      
    return xmlHttp;
  }

2. 사용 프로세스

1. 서버와의 연결을 엽니다(open)

XMLHttpRequest 객체, 객체의 open() 메서드를 호출하여 서버와의 연결을 열 수 있습니다. open() 메소드의 매개변수는 다음과 같습니다:

open(method, url, async):

method: 요청 메소드, 일반적으로 GET 또는 POST

url: 요청된 서버 주소(예: /ajaxdemo1/AServlet) , GET 요청인 경우 URL 뒤에 매개변수를 추가할 수도 있습니다.

async: 이 매개변수는 생략 가능하며 기본값은 비동기 요청을 나타냅니다.

var xmlHttp = createXMLHttpRequest(); "GET", " /ajax_get/?a=1", true)

2. 요청 보내기

open을 사용하여 연결을 연 후 XMLHttpRequest 개체의 send() 메서드를 호출하여 보낼 수 있습니다. 요청. send() 메소드의 매개변수는 POST 요청 매개변수이며, 이는 HTTP 프로토콜의 요청 본문 내용에 해당합니다. GET 요청인 경우 매개변수는 URL 뒤에 연결되어야 합니다.

참고: 매개변수가 없으면 매개변수로 null을 제공해야 합니다! null이 매개변수로 주어지지 않으면 FireFox 브라우저가 정상적으로 요청을 보내지 못할 수도 있습니다!

xmlHttp.send(null);

3. 서버 응답 수신(5개 상태, 4개 프로세스)

요청이 전송되면 서버가 실행을 시작하지만 서버 응답이 도착하지 않습니다. 다음으로 우리는 서버로부터 응답을 받습니다.

XMLHttpRequest 객체에는 XMLHttpRequest 객체의 상태가 변경될 때 호출되는 onreadystatechange 이벤트가 있습니다. 다음은 XMLHttpRequest 객체의 5가지 상태를 소개합니다.

0: 초기화가 완료되지 않았고 XMLHttpRequest 객체가 생성되었을 뿐이며 open() 메서드가 호출되지 않았습니다.

1: 요청이 시작되었으며 열려 있습니다. () 메소드가 호출되었지만 아직 open() 메소드가 호출되지 않았지만 send() 메소드를 호출합니다.

2: 전송 완료 상태 요청, send() 메소드가 호출되었습니다.

3: 읽기 시작;
4: 서버 응답 읽기가 끝났습니다.

onreadystatechange 이벤트는 상태가 1, 2, 3, 4일 때 트리거됩니다.

다음 코드는 4번 실행됩니다! XMLHttpRequest의 4가지 상태에 대응!

xmlHttp.onreadystatechange = function() {
      alert(&#39;hello&#39;);
    };

하지만 일반적으로 우리는 마지막 상태에만 관심이 있습니다. 즉, 클라이언트는 서버 응답을 읽을 때 변경 사항을 적용합니다. XMLHttpRequest 객체의 ReadyState 속성을 통해 XMLHttpRequest 객체의 상태를 얻을 수 있습니다.

xmlHttp.onreadystatechange = function() {
      if(xmlHttp.readyState == 4) {
        alert(&#39;hello&#39;);  
      }
    };

사실 서버 응답의 상태 코드 xmlHttp.status가 200인지도 신경써야 합니다. 서버 응답이 404나 500이면 요청이 실패한 것입니다. XMLHttpRequest 객체의 상태 속성을 통해 서버의 상태 코드를 얻을 수 있습니다.

마지막으로 서버 응답 내용도 가져와야 합니다. XMLHttpRequest 개체의 responseText를 통해 서버 응답 내용을 가져올 수 있습니다.

xmlHttp.onreadystatechange = function() {
      if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
        alert(xmlHttp.responseText);  
      }
    };

참고:

게시물 요청인 경우:

基于JS的ajax没有Content-Type这个参数了,也就不会默认是urlencode这种形式了,需要我们自己去设置
<1>需要设置请求头:xmlHttp.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);
注意 :form表单会默认这个键值对不设定,Web服务器会忽略请求体的内容。

<2>在发送时可以指定请求体了:xmlHttp.send(“username=yuan&password=123”)

基于jQuery的ajax和form发送的请求,都会默认有Content-Type,默认urlencode,

Content-Type:客户端告诉服务端我这次发送的数据是什么形式的
dataType:客户端期望服务端给我返回我设定的格式

get 요청인 경우:

 xmlhttp.open("get","/sendAjax/?a=1&b=2");

간단한 운동: 위의 운동과 동일하지만 방식이 다릅니다(비교 가능) jQuery 잠시만요)

<script>
方式一=======================================
  //基于JS实现实现用urlencode的方式
  var ele_btn = document.getElementsByClassName("send_ajax")[0];
  ele_btn.onclick = function () { //绑定事件
    alert(5555);
    //发送ajax:有一下几步
    //(1)获取XMLResquest对象
    xmlhttp = new XMLHttpRequest();
    //(2)连接服务器
    //get请求的时候,必用send发数据,直接在请求路径里面发
{#    xmlhttp.open(&quot;get&quot;,&quot;/sendAjax/?a=1&amp;b=2&quot;);//open里面的参数,请求方式,请求路径#}
    //post请求的时候,需要用send发送数据
    xmlhttp.open("post","/sendAjax/");
    //设置请求头的Content-Type
    xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    //(3)发送数据
    var ele_num1 = document.getElementsByClassName("num1")[0];
    var ele_num2 = document.getElementsByClassName("num2")[0];
    var ele_ret = document.getElementsByClassName("ret")[0];
    var ele_scrf = document.getElementsByName("csrfmiddlewaretoken")[0];
    var s1 = "num1="+ele_num1.value;
    var s2 = "num2="+ele_num2.value;
    var s3 = "&csrfmiddlewaretoken="+ele_scrf.value;
    xmlhttp.send(s1+"&"+s2+s3); //请求数据
    //(4)回调函数,success
    xmlhttp.onreadystatechange = function () {
      if (this.readyState==4&&this.status==200){
        alert(this.responseText);
        ele_ret.value = this.responseText
      }
    }
  }


方式二====================================================

{#  ===================json=============#}
  var ele_btn=document.getElementsByClassName("send_ajax")[0];
  ele_btn.onclick=function () {

    // 发送ajax

     // (1) 获取 XMLHttpRequest对象
     xmlHttp = new XMLHttpRequest();

     // (2) 连接服务器
    // get
    //xmlHttp.open("get","/sendAjax/?a=1&b=2");

    // post
    xmlHttp.open("post","/sendAjax/");

    // 设置请求头的Content-Type
    var ele_csrf=document.getElementsByName("csrfmiddlewaretoken")[0];
    xmlHttp.setRequestHeader("Content-Type","application/json");
    xmlHttp.setRequestHeader("X-CSRFToken",ele_csrf.value); //利用js的方式避免forbidden的解决办法

    // (3) 发送数据
     var ele_num1 = document.getElementsByClassName("num1")[0];
    var ele_num2 = document.getElementsByClassName("num2")[0];
    var ele_ret = document.getElementsByClassName("ret")[0];


    var s1 = ele_num1.value;
    var s2 = ele_num2.value;
    xmlHttp.send(JSON.stringify(
      {"num1":s1,"num2":s2}
    )) ;  // 请求体数据
    // (4) 回调函数 success
    xmlHttp.onreadystatechange = function() {
      if(this.readyState==4 && this.status==200){
        console.log(this.responseText);
        ele_ret.value = this.responseText
      }
    };
  }







</script>

views.py

def sendAjax(request):
  num1=request.POST.get("num1")
  num2 = request.POST.get("num2")
  ret = float(num1)+float(num2)
  return HttpResponse(ret)

JS实现ajax小结

创建XMLHttpRequest对象;
  调用open()方法打开与服务器的连接;
  调用send()方法发送请求;
  为XMLHttpRequest对象指定onreadystatechange事件函数,这个函数会在

  XMLHttpRequest的1、2、3、4,四种状态时被调用;

  XMLHttpRequest对象的5种状态,通常我们只关心4状态。

  XMLHttpRequest对象的status属性表示服务器状态码,它只有在readyState为4时才能获取到。

  XMLHttpRequest对象的responseText属性表示服务器响应内容,它只有在
  readyState为4时才能获取到!

总结:

- 如果"Content-Type"="application/json",发送的数据是对象形式的{},需要在body里面取数据,然后反序列化
= 如果"Content-Type"="application/x-www-form-urlencoded",发送的是/index/?name=haiyan&agee=20这样的数据,
 如果是POST请求需要在POST里取数据,如果是GET,在GET里面取数据

实例(用户名是否已被注册)

7.1 功能介绍

在注册表单中,当用户填写了用户名后,把光标移开后,会自动向服务器发送异步请求。服务器返回true或false,返回true表示这个用户名已经被注册过,返回false表示没有注册过。

客户端得到服务器返回的结果后,确定是否在用户名文本框后显示“用户名已被注册”的错误信息!

7.2 案例分析

页面中给出注册表单;

在username表单字段中添加onblur事件,调用send()方法;

send()方法获取username表单字段的内容,向服务器发送异步请求,参数为username;

django 的视图函数:获取username参数,判断是否为“yuan”,如果是响应true,否则响应false

参考代码:

<script type="text/javascript">
    function createXMLHttpRequest() {
      try {
        return new XMLHttpRequest();
      } catch (e) {
        try {
          return new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
          return new ActiveXObject("Microsoft.XMLHTTP");
        }
      }
    }

    function send() {
      var xmlHttp = createXMLHttpRequest();
      xmlHttp.onreadystatechange = function() {
        if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
          if(xmlHttp.responseText == "true") {
            document.getElementById("error").innerText = "用户名已被注册!";
            document.getElementById("error").textContent = "用户名已被注册!";
          } else {
            document.getElementById("error").innerText = "";
            document.getElementById("error").textContent = "";
          }
        }
      };
      xmlHttp.open("POST", "/ajax_check/", true, "json");
      xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      var username = document.getElementById("username").value;
      xmlHttp.send("username=" + username);
    }
</script>

//--------------------------------------------------index.html

<h1>注册</h1>
<form action="" method="post">
用户名:<input id="username" type="text" name="username" onblur="send()"/><span id="error"></span><br/>
密 码:<input type="text" name="password"/><br/>
<input type="submit" value="注册"/>
</form>


//--------------------------------------------------views.py
from django.views.decorators.csrf import csrf_exempt

def login(request):
  print(&#39;hello ajax&#39;)
  return render(request,&#39;index.html&#39;)
  # return HttpResponse(&#39;helloyuanhao&#39;)

@csrf_exempt
def ajax_check(request):
  print(&#39;ok&#39;)

  username=request.POST.get(&#39;username&#39;,None)
  if username==&#39;yuan&#39;:
    return HttpResponse(&#39;true&#39;)
  return HttpResponse(&#39;false&#39;)

三、同源策略与jsonp

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
jsonp(jsonpadding)

之前发ajax的时候都是在自己给自己的当前的项目下发

现在我们来实现跨域发。给别人的项目发数据,

创建两个项目,先来测试一下

项目一:

<body>
<h1>项目一</h1>
<button class="send_jsonp">jsonp</button>
<script>
  $(".send_jsonp").click(function () {
    $.ajax({
      url:"http://127.0.0.1:8080/ajax_send2/",  #去请求项目二中的url
      success:function (data) {
        console.log(data)
      }
    })
  })
</script>
</body>

项目二:

=========================index.html===============
<h1>项目二</h1>
<button class="send_jsonp">jsonp</button>
<script>
  $(".send_jsonp").click(function () {
    $.ajax({
      url:"/ajax_send2/",
      success:function (data) {
        console.log(data)
      }
    })
  })
</script>
</body>

=========================views===============

from django.shortcuts import render,HttpResponse

# Create your views here.
def index(request):
  return render(request, "index.html")
def ajax_send2(request):
  print(222222)
  return HttpResponse("hello")

出现了一个错误,这是因为同源策略给限制了,这是游览器给我们报的一个错

(但是注意,项目2中的访问已经发生了,说明是浏览器对非同源请求返回的结果做了拦截。)

注意:a标签,form,img标签,引用cdn的css等也属于跨域(跨不同的域拿过来文件来使用),不是所有的请求都给做跨域,(为什么要进行跨域呢?因为我想用人家的数据,所以得去别人的url中去拿,借助script标签)

如果用script请求的时候也会报错,当你你返回的数据是一个return Httpresponse(“项目二”)只是一个名字而已,js中如果有一个变量没有声明,就会报错。就像下面的这样了

<script src="http://127.0.0.1:8080/ajax_send2/">
  项目二
</script>

只有发ajax的时候给拦截了,所以要解决的问题只是针对ajax请求能够实现跨域请求

解决同源策源的两个方法:

1、jsonp(将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。)

jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。

思考:这算怎么回事?

<script src="http://code.jquery.com/jquery-latest.js"></script>

借助script标签,实现跨域请求,示例:

所以只是单纯的返回一个也没有什么意义,我们需要的是数据

如下:可以返回一个字典,不过也可以返回其他的(简单的解决了跨域,利用script)

项目一:

<body>
<h1>项目一</h1>
<button class="send_jsonp">jsonp</button>
<script>
  $(".send_jsonp").click(function () {
    $.ajax({
      url:"",
      success:function (data) {
        console.log(data)
      }
    })
  });

  function func(arg) {
    console.log(arg)
  }
</script>
<script src="http://127.0.0.1:8080/ajax_send2/"></script>
</body>

项目二:

def ajax_send2(request):
  import json
  print(222222)
  # return HttpResponse("func(&#39;name&#39;)")
  s = {"name":"haiyan","age":12}
  # return HttpResponse("func(&#39;name&#39;)")
  return HttpResponse("func(&#39;%s&#39;)"%json.dumps(s))  #返回一个func()字符串,正好自己的ajax里面有个func函数,就去执行func函数了,
                                arg就是传的形参

这样就会取到值了

这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。

但是以上的方式也有不足,回调函数的名字和返回的那个名字的一致。并且一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。

解决办法:javascript动态的创建script标签

===========================jQuery实现=====================
{#  创建一个script标签,让他请求一次,请求完了删除他#}
  //动态生成一个script标签,直接可以定义个函数,放在函数里面
  function add_script(url) {
    var ele_script = $("<script>");
    ele_script.attr("src",url);
    ele_script.attr("id","script");
    $("body").append(ele_script);
    $("#script").remove()
  }
  $(".kuayu").click(function () {
    add_script("http://127.0.0.1:8080/ajax_send2/")
  });


</script>



==================js实现==========================
<button onclick="f()">sendAjax</button>

<script>
  function addScriptTag(src){
     var script = document.createElement(&#39;script&#39;);
     script.setAttribute("type","text/javascript");
     script.src = src;
     document.body.appendChild(script);
     document.body.removeChild(script);
  }


  function func(name){
    alert("hello"+name)
  }

  function f(){
     addScriptTag("http://127.0.0.1:7766/SendAjax/")
  }
</script>

为了更加灵活,现在将你自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调:

function f(){
     addScriptTag("http://127.0.0.1:7766/SendAjax/?callbacks=func")
  }

将视图views改为

def SendAjax(request):
 
  import json
 
  dic={"k1":"v1"}
 
  print("callbacks:",request.GET.get("callbacks"))  
  callbacks=request.GET.get("callbacks")  #注意要在服务端得到回调函数名的名字
 
  return HttpResponse("%s(&#39;%s&#39;)"%(callbacks,json.dumps(dic)))

四、jQuery对JSONP的实现

getJSON

jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法

<button onclick="f()">sendAjax</button>

<script>

  function f(){
     $.getJSON("http://127.0.0.1:7766/SendAjax/?callbacks=?",function(arg){
      alert("hello"+arg)
    }); 匿名函数
  }
  
</script>

8002的views不改动。

结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个?是内部自动生成的一个回调函数名。

此外,如果说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现

$.ajax

<script>

  function f(){
     $.ajax({
        url:"http://127.0.0.1:7766/SendAjax/",
        dataType:"jsonp",  
        jsonp: &#39;callbacks&#39;,  #键
          jsonpCallback:"SayHi" #函数的名字
 }); } function SayHi(arg){ alert(arg); } </script>

8002的views不改动。

当然,最简单的形式还是通过回调函数来处理:

<script>

  function f(){

      $.ajax({
        url:"http://127.0.0.1:7766/SendAjax/",
        dataType:"jsonp",      //必须有,告诉server,这次访问要的是一个jsonp的结果。
        jsonp: &#39;callbacks&#39;,     //jQuery帮助随机生成的:callbacks="wner"
        success:function(data){
          alert("hi "+data)
       }
     });

    }

</script>

jsonp: 'callbacks'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名'SayHi',server端接受callback键对应值后就可以在其中填充数据打包返回了;

jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。利用jQuery可以很方便的实现JSONP来进行跨域访问。  

注意 JSONP一定是GET请求

五、应用

// 跨域请求实例
  $(".jiangxiTV").click(function () {

    $.ajax({
      url:"http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403",
       dataType: &#39;jsonp&#39;,
       jsonp: &#39;callback&#39;,
       jsonpCallback: &#39;list&#39;,
       success:function (data) {
         console.log(data.data);  // [{},{},{},{},{},{}]
         week_list=data.data;
         
         $.each(week_list,function (i,j) {
           console.log(i,j); // 1 {week: "周一", list: Array(19)}
           s="<p>"+j.week+"列表</p>";
           $(".show_list").append(s);

           $.each(j.list,function (k,v) { // {time: "0030", name: "通宵剧场六集连播", link: "http://www.jxntv.cn/live/jxtv2.shtml"}
             a="<p><a href=&#39;"+v.link+"&#39;>"+v.name+"</a></p>";
             $(".show_list").append(a);
           })
         })
         
       }
    })


  })

相关推荐:

AJAX的常用语法是什么

几种javascript实现原生ajax的方法

jQuery一个ajax实例

위 내용은 JS에서 구현한 Ajax 및 Same Origin 전략에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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