跨域的三种方式


title: 跨域 date: 2019-02-14 08:45:33 tags: [跨域]

跨域

什么是跨域为什么要跨域 ?

浏览器对于JavaScript的同源策略的限制,例如a.cn不能调用b.js的数据。也是属于对网站的一种保护机制

同源策略:

是指

  • 相同域名
  • 相同端口
  • 相同协议

跨域的三种方式

cls 服务端跨域 一

我们先模拟出不符合同源策略的生产环境

服务端代码

在这里是在这里是通过gulp起了一个8080的端口

const gulp = require('gulp')
const webserver = require('gulp-webserver')
gulp.task("server", () => {
    gulp.src('./')
        .pipe(webserver({
            host: "localhost",
            port: 8080,
            middleware(req, res) {
                const data = { name: "neinei", age: 19 }
                res.writeHead(200, {
                    'Content-Type': 'application/json;charset=utf-8',
                })
                res.end(JSON.stringify(data))
            }
        }))
})

复制代码

客户端js代码通过gulp起了一个人端口8000的端口 然后把html页面返回到浏览器

let fs = require("fs")
const gulp = require("gulp")
const webserver = require("gulp-webserver")
let result = fs.readFileSync("./index.html", "utf-8")
gulp.task("api", () => {
    gulp.src('./')
        .pipe(webserver({
            host: "localhost",
            port: 8000,
            middleware(req, res) {
                res.end(result)
            }
        }))
})
复制代码

客户端html展示页面代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    this is page
<script>
function request(url) {
    return new Promise((resolve, reject) => {
        let xml = new XMLHttpRequest()
        xml.open("GET", url, false)
        xml.onreadystatechange = function () {
            if(xml.readyState!=4)return false
            if(xml.status===200){
                resolve(xml.responseText)
            }
        }
        xml.send()
    })
}

request('http://localhost:8080').then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err)
})
</script>
</body>
</html>
复制代码

在这里起了两个服务一个端口为8080一个端口为8000满足了跨域的需求 发起ajax试一下

添加语法 'Access-Control-Allow-Origin': '*' 服务端代码

const gulp = require('gulp')
const webserver = require('gulp-webserver')
gulp.task("server", () => {
    gulp.src('./')
        .pipe(webserver({
            host: "localhost",
            port: 8080,
            middleware(req, res) {
                const data = { name: "neinei", age: 19 }
                res.writeHead(200, {
                    'Content-Type': 'application/json;charset=utf-8',
                    'Access-Control-Allow-Credentials': true,
                    'Access-Control-Allow-Origin': '*'
                })
                res.end(JSON.stringify(data))
            }
        }))
})

复制代码

Access-Control-Allow-Origin

Access-Control-Allow-Origin 响应头指定了该响应的资源是否被允许与给定的origin共享
复制代码
*
对于不需具备凭证(credentials)的请求,服务器会以“*”作为通配符,从而允许所有域都具有访问资源的权限。
<origin>
指定一个可以访问资源的URI。

jsonp跨域 二

jsonp的原理

通过html中带有src属性的标签发起请求

src:因为src不受同源策略影响

一般使用<script>标签

在请求路由中带去一个回调函数, 在服务端返回执行。

就可以在函数中的形参中拿到数据

服务端代码 端口号 8888

var http = require('http');
var url = require('url')
var data = JSON.stringify({ name: "heihei", age: 21 })
http.createServer(function (request, response) {
    var parse = url.parse(request.url, true)
    response.writeHead(200, { 'Content-Type': 'text/plain' });
    if (parse.query.callback) {
        response.end(parse.query.callback+"("+data+")")
        return
    }
    response.end(data);
}).listen(8888, () => {
    console.log(8888)
});
复制代码

客户端代码 端口8000

let fs = require("fs")
const gulp = require("gulp")
const webserver = require("gulp-webserver")
let result = fs.readFileSync("./index.html", "utf-8")
gulp.task("api", () => {
    gulp.src('./')
        .pipe(webserver({
            host: "localhost",
            port: 8000,
            middleware(req, res) {
                res.end(result)
            }
        }))
})
复制代码

客户端html代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    this is page
    <script>
        function cb(data) {
            console.log(data)
        }
        var script = document.createElement('script')
        script.setAttribute('src', "http://localhost:8888?callback=cb")
        document.body.appendChild(script)

    </script>
</body>

</html>
复制代码
客户端
  • 动态创建一个script标签

  • 创建一个函数来接受来接收数据 如上代码 我们创建了一个cb函数

  • 设置src属性为我们的接口地址 http://localhost:8888?callback=cb

  • 通过appendChild方法吧script插入body插入后会自动发起请求

服务端
  • 解析客户端传来的参数,通过node模块中的url模块来解析

url.parse:解析前端的请求参数 第二个参数为true时会把参数解析成对象

parse.query:会把参数解析放在parse.query的对象中


 var parse = url.parse(request.url, true)
复制代码
  • 判断是否传来callback函数然后通过end返回
 if (parse.query.callback) {
        response.end(parse.query.callback+"("+data+")")
        return
    }
复制代码
  • 服务端的函数接收数据
 function cb(data) {
            console.log(data)
        }
复制代码

降域 三

域名为http://b.com/b的网页以iframe的形式嵌在域名为http://a.com/a的网页中,它们来自不同的域名,正常情况下不能进行跨域访问。

但是当我们为两个页面都加上这样一句代码:

document.domain = 'wuxiaozhou.com';

这时候这两个页面就位于同一个域名下面了,就可以在页面a中对页面b进行操作了,两个页面可以互相访问。

项目地址: github.com/wangjinshen…

转载于:https://juejin.im/post/5c921d6ce51d454cc35d96d3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值