美文网首页
跨域的几种方式

跨域的几种方式

作者: 东郭皮蛋 | 来源:发表于2019-03-01 20:44 被阅读0次

JSONP

html中script标签可以引入其他域下的js,比如引入线上的jquery库。利用这个特性,可实现跨域访问接口。不过需要后端支持。
web页面中,通过script标签获取js代码可以进行跨域,我们可以动态的创建script标签,设置src属性指向我们请求资源的url地址,然后放到head标签中。这样就可以把不同域的数据加载到本域名下,不过需要后端支持jsonp,也就是通过前端的url中的callback参数动态的生成回调函数名,通过传参的形式执行获取到的数据,这样的话,前端预定义好的函数就可以让传来的数据自动运行。

演示:

server.js

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

http.createServer(function(req, res){
  var pathObj = url.parse(req.url, true)

  switch (pathObj.pathname) {
    case '/getNews':
      var news = [
        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
        "正直播柴飚/洪炜出战 男双力争会师决赛",
        "女排将死磕巴西!郎平安排男陪练模仿对方核心"
        ]
      res.setHeader('Content-Type','text/json; charset=utf-8')
      if(pathObj.query.callback){
        res.end(pathObj.query.callback + '(' + JSON.stringify(news) + ')')
      }else{
        res.end(JSON.stringify(news))
      }

      break;

    default:
      fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
        if(e){
          res.writeHead(404, 'not found')
          res.end('<h1>404 Not Found</h1>')
        }else{
          res.end(data)
        }
      }) 
  }
}).listen(8080)

index.html

<!DOCTYPE html>
<html>
<body>
  <div class="container">
    <ul class="news">
    </ul>
    <button class="show">show news</button>
  </div>

<script>

  $('.show').addEventListener('click', function(){
    var script = document.createElement('script');
    script.src = 'http://127.0.0.1:8080/getNews?callback=appendHtml';
    document.head.appendChild(script);
    document.head.removeChild(script);
  })

  function appendHtml(news){
    var html = '';
    for( var i=0; i<news.length; i++){
      html += '<li>' + news[i] + '</li>';
    }
    console.log(html);
    $('.news').innerHTML = html;
  }

  function $(id){
    return document.querySelector(id);
  }
</script>

</html>

打开终端,输入 node server.js ,浏览器打开 http://localhost:8080/index.html


CORS

CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。 实现方式很简单,当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以 CORS 的表象是让你觉得它与同源的 ajax 请求没啥区别,代码完全一样。

server.js


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

http.createServer(function(req, res){
  var pathObj = url.parse(req.url, true)

  switch (pathObj.pathname) {
    case '/getNews':
      var news = [
        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
        "正直播柴飚/洪炜出战 男双力争会师决赛",
        "女排将死磕巴西!郎平安排男陪练模仿对方核心"
        ]

      res.setHeader('Access-Control-Allow-Origin','http://localhost:8080')
      //res.setHeader('Access-Control-Allow-Origin','*')
      res.end(JSON.stringify(news))
      break;
    default:
      fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
        if(e){
          res.writeHead(404, 'not found')
          res.end('<h1>404 Not Found</h1>')
        }else{
          res.end(data)
        }
      }) 
  }
}).listen(8080)

index.html

<!DOCTYPE html>
<html>
<body>
  <div class="container">
    <ul class="news">

    </ul>
    <button class="show">show news</button>
  </div>

<script>

  $('.show').addEventListener('click', function(){
    var xhr = new XMLHttpRequest()
    xhr.open('GET', 'http://127.0.0.1:8080/getNews', true)
    xhr.send()
    xhr.onload = function(){
      appendHtml(JSON.parse(xhr.responseText))
    }
  })

  function appendHtml(news){
    var html = ''
    for( var i=0; i<news.length; i++){
      html += '<li>' + news[i] + '</li>'
    }
    $('.news').innerHTML = html
  }

  function $(selector){
    return document.querySelector(ctor)
  }
</script>

</html>

启动终端,执行 node server.js ,浏览器打开 http://localhost:8080/index.html ,查看效果和网络请求

效果 网络请求

降域

降域是相对于iframe元素而言的 。
一般来说域名为http://b.test.com/b(A)的网页以iframe的形式嵌在域名为http://a.test.com/a(B)的网页中,浏览器发现该请求不符合同源策略,正常情况下不能进行跨域访问,但是当我们在两个页面中分别设置documet.domain = test.com的时候(注意观察这个方法有一个限制就是 域名中必须有相同的部分),B页面就可以访问到A页面中的资源了。

演示:

a.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>a</title>
  <style>
    .ct{
      width: 910px;
      margin: auto;
    }
    .main{
      float: left;
      width: 450px;
      height: 300px;
      border: 1px solid #ccc;
    } 
    .main input {
      margin: 20px;
      width: 200px; 
    }
    .iframe{
      float: right;
    }
    iframe{
      width: 450px;
      height: 300;
      border: 1px dashed #ccc;
    }
  </style>
</head>
<body>
  <div class="ct">
    <h1>使用降域实现跨域</h1>
    <div class="main">
      <input type="text" placeholder="http://a.jrg.com:8080/a.html">
    </div>
    <iframe src="http://b.jrg.com:8080/b.html" frameborder="0"></iframe>
  </div>

  <script>
  document.querySelector('.main input').addEventListener('input', function(){
    console.log(this.value)
    window.frames[0].document.querySelector('input').value = this.value
  })
  // document.domain = 'jrg.com'
  </script>
</body>
</html>

b.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>b</title>
  <style>
    html,body{
        margin: 0; 
    }
    input {
        margin: 20px; 
        width: 200px;
    }
  </style>
</head>
<body>

  <input type="text" placeholder="http://a.jrg.com:8080/a.html">

  <script>
  document.querySelector('.main input').addEventListener('input', function(){
    console.log(this.value)
    window.frames[0].document.querySelector('input').value = this.value
  })
  document.domain = 'jrg.com'
  </script>
</body>
</html>
未执行document.domain = 'jrg.com'

postMessage()

window.postMessage()是HTML5的新方法,可以使用它来向其它的window对象发送数据,无论这个window对象是属于同源或不同源,IE8+支持。

postMessage(data, origin)方法接收两个参数

  1. data:要传递的数据。html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。
  2. origin:字符串参数,用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 * ,这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"

演示:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>a</title>
  <style>
    .ct{
      width: 910px;
      margin: auto;
    }
    .main{
      float: left;
      width: 450px;
      height: 300px;
      border: 1px solid #ccc;
    } 
    .main input {
      margin: 20px;
      width: 200px; 
    }
    .iframe{
      float: right;
    }
    iframe{
      width: 450px;
      height: 300;
      border: 1px dashed #ccc;
    }
  </style>
</head>
<body>
  <div class="ct">
    <h1>使用postMessage实现跨域</h1>
    <div class="main">
      <input type="text" placeholder="http://a.jrg.com:8080/a.html">
    </div>
    <iframe src="http://localhost:8080/b.html" frameborder="0"></iframe>
  </div>

  <script>
  $('.main input').addEventListener('input', function(){
    console.log(this.value)
    window.frame[0].postMessage(this.value, '*')
  })
  window.addEventListener('message', function(e){
    $('.main input').value = e.data
    console.log(e.data)
  })
  function $(id){
    return document.querySelector(id)
  }
  </script>
</body>
</html>

b.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>b</title>
  <style>
    html,body{
        margin: 0; 
    }
    input {
        margin: 20px; 
        width: 200px;
    }
  </style>
</head>
<body>

  <input id="input" type="text" placeholder="http://b.jrg.com:8080/a.html">

  <script>
  $('#input').addEventListener('input', function(){
    window.frame[0].postMessage(this.value, '*')
  })
  window.addEventListener('message', function(e){
    $('#input').value = e.data
    console.log(e.data)
  })
  function $(id){
    return document.querySelector(id)
  }
  </script>
</body>
</html>

相关文章

  • Ajax 请求和跨域

    跨域的几种方式: cors方式 cross-orign-resource-shareing(跨域)参考:http:...

  • #hello,JS:15 同源策略 & 跨域(JSONP)

    跨域有几种常见的方式?你有没有跨域使用的经验? 方式: 使用jsonp实现跨域?使用cors实现跨域?浏览器另类的...

  • 跨域问题

    前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 一、什么是跨域? 广义...

  • JavaScript 九种跨域方式实现原理

    前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 一、什么是跨域?...

  • JavaScript 九种跨域方式实现原理

    前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 一、什么是跨域?...

  • JavaScript 九种跨域方式实现原理【转】

    前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 一、什么是跨域?...

  • 九种跨域方式实现原理(完整版)

    前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 一、什么是跨域?...

  • 常见前端开发面试题(http部分)

    跨域有哪几种方式 1.jsonp跨域2.CORS跨域资源共享3.iframe标签跨域4.在webpack中通过配置...

  • 九种跨域方式实现原理

    前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 一、什么是跨域? 1....

  • 跨域

    前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 1. 什么是跨域...

网友评论

      本文标题:跨域的几种方式

      本文链接:https://www.haomeiwen.com/subject/ezqldqtx.html