AJAX和跨域

JSONP

  • 什么是JSONP?

    1
    2
    3
    4
    5
    1.请求方:一个网站的前端   响应方:服务器
    2.请求方动态的创建一个script标签,src指向的是响应方,同时传递一个查询参数?callback = xxxx
    3.响应方通过传递的查询参数?callback创建一个形如xxx.call(undefined,"你想要的数据")
    4.请求方接受响应方发出的响应的时候,就会执行xxx.call(undefined."你想要的参数")
    5.请求方得到了想要的数据,并且删除script。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    请求方的代码:
    <!DOCTYPE html>
    <html lang="zh-Hans">

    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>首页</title>
    <link rel="stylesheet" href="/style.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
    </head>

    <body>
    <p>您的账户余额是
    <span id="amount">$$$amount$$$</span>
    </p>
    <button id="button">付款</button>
    </body>
    <script>

    button.addEventListener('click', (x) => {
    let script= document.createElement('script')
    let functionName = 'frank' + parseInt(Math.random()*10000,10)
    //创建一个函数名称,使得传过去的查询参数是一个随机数。
    window[functionName] =(result)=>{
    if(result === 'success'){
    alert(`${result}`)
    amount.innerText = amount.innerText - 1
    }else{
    alert(faile)
    }
    }//因为functionName是一个随机数,不确定的因素,所以不能使用functionName.xxx 只能使用[]
    script.src = 'http://jack.com:8002/pay?callback=' + functionName//添加查询参数,使得可以知道调用的函数是xxx
    //动态的创建了一个script标签在页面之中。并在成功之后删除该script标签,否则会占用过多的内存。
    document.body.appendChild(script)
    script.onload = function(e){
    e.currentTarget.remove()
    script.onerror = function(e){
    e.currentTarget.remove()
    alert('打钱失败')
    }
    }

    /* image.src = '/pay'
    image.onload=function(){
    alert('打钱成功')
    amount.innerText = amount.innerText - 1
    }
    image.onerror =function(){
    alert('打钱失败failse')
    }*/
    })
    </script>

    </html>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    响应方的代码:
    if(path === '/pay'){
    var amount =fs.readFileSync('./amount','utf8')
    //获取数据库中的amount数据。
    var newAmount = amount - 1
    fs.writeFileSync('./amount',newAmount)
    //得到新的数据,并将新的数据存在数据库之中。
    response.setHeader('Content-Type', 'applycation/script')
    response.statusCode = 200
    //成功返回状态码200; response.write(`${query.callback}.call(undefined,'success')`)//得到查询参数
    response.end()
    }
    else{
    response.statusCode = 404
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write('找不到对应的路径,你需要自行修改 index.js')
    response.end()
    }
  • 上面描述的是过程,请求方可以使用jQuery就可以发送JSONP请求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    button.addEventListener('click', (x) => {

    $.ajax({
    url: "http://jack.com:800/pay",
    // Tell jQuery we're expecting JSONP
    dataType: "jsonp",
    // Work with the response
    success: function (response) {
    if(response === "success"){
    alert(`${response}`)
    amount.innerText = amount.innerText - 1
    }else{
    alert('failse')
    }
    }
    });
    * JQuery会帮你创建一个script标签向服务器发送请求,也会创建一个随机的查询参数,也会创建更一个函数,服务器接受到这个函数后并返回这个函数,请求方会调用这个函数。

AJAX

  • AJAX发送请求是怎样出现的呢:

    1.用form发送请求会刷新页面或重开页面的。(可以发送get请求或者POST请求)

    2.使用a标签发送请求GET请求,也会刷新页面,或者重开页面的。

    3.用img标签可以发送GET请求,但是只能以图片的形式展示。

    4.用link可以发送GET请求,也只能以CSS或者favicon的形式运行,并且link只能放在页面之中才能够运行的。

    5.用script发送请求,只能以脚本的形式运行。

  • 什么是AJAX呢:

    1.使用XMLHttpRequest发送请求

    2.返回的是XML格式的字符串/也可以是别的额类型的字符串代替的XML,也算是AJAX。

    3,JS进行解析,并更新局部页面

  • HTTP中的路径都是绝对路径

  • 使用AJAX发送请求的过程:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let request = new XMLHttpRequest
    request.open("POST","/xxx")//设置请求的路径和请求的格式
    request.setHeader()//设置请求的头部。
    request.onreadystatechange = (x)=>{
    if(request.readystate === 4){
    let string = request.responseText
    let object = window.JSON.parse(string)
    }else
    }
    request.sed() //发送请求
  • readyState中0表示open()方法还未被调用;1表示send()方法还未被调用;2表示send()方法已经被调用;3表示正在下载,loading;4表示请求完成。响应返回是分不分返回的,并不是一次性返回的。

  • 同源策略:只有当域名、协议、端口号一模一样的时候才叫同源;才能够发送AJAX请求,不是同源的可以通过CORS也能够使用AJAX发送请求。response.setHeader('Content-type','application/javascript;charset =utf-8')。除了使用CORS还可以使用的是JSONP来进行跨域。

请求的设置

  • 使用XMLHttpRequest来进行发送请求的时候,XMLHttpRequest.open('请求的方式','Host和路径'),可以使用XMLHtttpRequest.sretRequestHeader('请求的头部')来设置请求的头部,接受两个参数,第一个是属性的名字,第二个是value值。XMLHttpRequest.send(body)可以设置请求的第四部分的内容。

响应的获取

  • 使用XMLHttpRequest来发送请求后,服务器返回响应。可以通过XMLHttpRequest.getAllResponseHeasers()可以获取所有的响应的头部。如果只想获取其中的一个可以使用XMLHttpRequest.getHeader();XMLHttpRequest.statusText()可以获取到OK;XMLHttpRequest.status()可以获取到响应的status,一般都是200。获取响应的第四部分可以使用XMLHttpRequest.responseText()

自己封装实现一个ajax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
window.jQuery = function (nodesorSlector) {
let nodes = {}
nodes.addClass = function () { }
nodes.removeClass = function () { }
return nodes
}
window.$ = window.jQuery
//add a ajax attribute;accept parameter;给jQuery添加了一个ajax的属性,接收的参数。
widnow.jQuery.ajax = function (options) {
let url = options.url
let method = options.method
let body = options.body
let successFn =options.successFn
let failFn = options.failFn
let request = new XMLHttpRequest()
request.open('method', 'url')//配置request
request.onreadystatechange = () => {
if (request.readyState !== 4) {
}
if (request.status >= 200 && request.status < 300) {
successFn.call(undefined,request.responseText)
} else if (request.status >= 400) {
failFn.call(undefined,request)
}
}
request.send(body)
}
myButton.addEventListener('click',()=>{
window.jQuery.ajax({
url:'/xxx',
method:'get',
body:'1&2',
successFn:()=>{console.log(1)},
failFn:()=>{console.log(20)}
})
})
在JS中如果想要给参数命名的话,就可以使用一个对象。一般都是采用这种方式的。因为obj只使用了一次,就可以将这个对象整个传进去。而不使用变量。