什么是同源策略,几种简单跨域请求的办法

狂风中的少年 提交于 2019-12-02 10:45:24
  1. 先解释一下什么是同源
    同源代表同协议、同域名、同端口。
    例如: http://www.baidu.com:80
    http 协议、 www.baidu.com 域名、 80 端口
    (插入一个小知识 http的默认端口是80 https的默认端口是443)
    只有两个页面的三者全部相同时,其中一个页面才能获取另一个页面里面的信息。

  2. 为什么要有同源策略
    同源策略主要是为了各个页面之间的信息安全。
    如果没有同源策略,不同源的http请求可以随意拿到其它网站的信息,那么就没有隐私可言了。完全可以通过iframe获取到你登陆的用户名和密码。

  3. 怎么做到跨域请求
    #通过没有同源限制的标签中的属性可以做到跨域
    link的href属性 iframe的src属性 script的src属性
    img的src属性

<img width="60" src="https://www.lgstatic.com/i/image/M00/B9/9E/CgqKkVjDiXOAPaljAAL0RuLm39Q629.jpg" >

#通过服务器代理进行跨域请求

//在接口中封装一个请求server
const express = require("express");//引入express模块
const request = require("request");//服务器代理必须使用request模块
const app = express();//使用express
app.all("*",function (req,res,next) {//每个请求都必须先经过app.all
    res.header("Access-Control-Allow-Origin","*");//通过同源策略
    next();//请求不结束,进行下一个请求
})
// https://m.lagou.com/listmore.json?pageNo=2&pageSize=15&callback=fn
app.get("/listmore",function (req,res) {//请求信息所在的文件夹
    const {pageNo,pageSize} = req.query;//传入所需要的第几页和每页多少条多少信息
    //使用反引号将变量写入地址里面
    request(`https://m.lagou.com/listmore.json?pageNo=${pageNo}&pageSize=${pageSize}`,function (err,response,body) {
    //在不报错且请求状态码是200时返回信息
        if(!err && response.statusCode === 200){
            res.json(JSON.parse(body));
        }else{
            res.json({
                ok:1,
                msg:"异常"
            });
        }
    })
})
//在html的请求  使用vue的mounted钩子函数
        async mounted(){//异步请求 使用async
                const {data} = await this.$http.get("http://127.0.0.1/listmore",{//本机地址
                    pageNo,//传入参数
                    pageSize:10
                })
                this.result = data.content.data.page.result;//将请求到的结果放入vue的data里面  可以进行处理后放到html里面
        },

#通过jsonp请求
jsonp是处理跨域请求的一个常用方式
在两个公司进行合作时经常使用jsonp来进行访问,让合作伙伴可以访问自己网站信息的同时,又不存在扰乱自己网站数据的可能。

//字面量对象 封装jsonp请求
const feng ={
     //传送数据格式  ?xxx=xx&cb=a
        //属性jsonp url 接收地址 query 接收参数  指定传递数据的函数名jsonp
    jsonp(url,query={},{jsonp}){
        //返回一个promise
        return new Promise(resolve=>{
            //定义返回结果 response
            const response = {
                state :200
            }
            //生成随机函数名(jquery_时间戳_5位随机数)
            query[jsonp] = "jquery_"+Date.now()+"_"+(Math.random()*10000000).toString().substr(0,5)
            //全局创建函数 该函数会在接口中执行 并传递参数
            window[query[jsonp]] = function(obj){
                response.data =obj
            }
            const script = document.createElement("script");
            //script标签增加一个地址
            script.src = url +"?"+ Object.keys(query).map(v=>v+"="+query[v]).join("&")
            //异步
            script.async = true;
            //接受加载的结果  并返回
            function handler(ev){
                document.body.removeChild(script)
                //用完之后删掉函数
                delete window[query[jsonp]]
                if(ev.type === "error"){
                    response.state= 404;
                    response.msg = "网络连接错误"
                }   
                resolve(response);
            }
            script.onload = handler;
            script.onerror = handler;
            document.body.appendChild(script)
        })
    }
}

export default feng;

在html中使用ajax进行请求

search(e){
            //下键搜索
            if(e.keyCode === 40){
                this.index++;
                if(this.index>this.g.length-1){
                    this.index=-1
                }else{
                    this.keyword = this.g[this.index].q
                }
                //上键搜索
            }else if(e.keyCode === 38){
                this.index--;
                if(this.index<-1){
                    this.index = this.g.length-1
                }else{
                    this.keyword = this.g[this.index].q
                }
            }
            //上下键都不是  触发jsonp请求
            //https://www.baidu.com/sugrec?prod=pc&wd=a&cb=jquery_时间戳+随机数字5位
            else{
                this.$http.jsonp("https://www.baidu.com/sugrec",{
                prod:"pc",
                wd:this.keyword
            },{
                //自定义cb
                jsonp:"cb"
                //成功后结构数组  返回data等
            }).then(({state,data,msg})=>{
                if(state === 200){
                    console.log(data)
                    //g位返回的数组
                    this.g = data.g;
                    //input中输入的内容
                    this.q = data.q;
                }else{
                    //失败返回   请求失败
                    console.log(msg)
                }
            })
            }
            
        }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!