jsonp跨域简单实现

85 阅读1分钟

同源策略

基于安全的考虑,现如今浏览器中都引入了同源策略。所说的同源就是协议、域名、端口这三个都相同

例如:对于http://www.example.com/a.js。协议是http,域名是www.example.com,端口默认为80

http://www.example.com/b.js         同源
http://www.example.com:8080/a.js    不同源
http://www.example123.com/a.js      不同源
https://www.example.com/a.js        不同源      

受同源策略的限制,对于非同源之间是不能发送AJAX请求的

创建文件a.js,在其中任意编写一些内容

var a = 'jsonp'

在同一目录下创建文件index.js,用node开启一个服务器

var http = require('http')
var fs = require('fs')

var server = http.createServer()

server.on('request', function (req, res) {
  if (req.url === '/a.js') {
    fs.readFile('./a.js', 'utf-8', function (err, data) {
      if (err) {
        res.end(err)
      } else {
        res.end(data)
      }
    })
  }
})

server.listen(3000, function () {
  console.log('3000 port is open')
})

创建文件index.html,发起AJAX请求,访问服务器中的文件a.js

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>jsonp</title>
</head>
<body>

  <script>
    var xhr = new XMLHttpRequest()   
    xhr.open('get', 'http://127.0.0.1:3000/a.js') 
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4 && xhr.status === 200) {     // 将响应的结果输出到控制台
        console.log(xhr.responseText)
      }
    }
    xhr.send()

  </script>

</body>
</html>

从控制台的输出可以看到AJAX请求不能跨域

jsonp的简单实现

解决跨域访问的方法有很多,jsonp就是其中一种。它是借助script标签能跨域加载数据的特性来实现的

对之前的文件index.js做一些修改,通过解析url来获得url中携带的参数

var http = require('http')
var fs = require('fs')
var url = require('url')

var server = http.createServer()

server.on('request', function (req, res) {  
  url = url.parse(req.url, true)
  if (url.pathname === '/a.js') {
    fs.readFile('./a.js', 'utf-8', function (err, data) {
      if (err) {
        res.end(err)
      } else {
        res.end(url.query.callback + '(' + JSON.stringify(data) + ')')
      }
    })
  }
})

server.listen(3000, function () {
  console.log('3000 port is open')
})

创建文件jsonp.html,借助script标签访问服务器所在的文件a.js

<!DOCTYPE html><html lang="en"><head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script>
    function fun (data) {
      console.log(data)
    }
    var s = document.createElement('script')
    var url = 'http://127.0.0.1:3000/a.js?callback=fun'
    s.setAttribute('src', url)
    document.getElementsByTagName('head')[0].appendChild(s)
  </script>
</head><body></body>
</html>

查看控制台输出,成功访问到了a.js中的数据,jsonp跨域成功

jsonp优缺点

优点:不受同源策略的限制,兼容性也很好

缺点:它只支持get请求而不支持post等其它类型的请求