js中如何解决跨域问题

首先介绍一下js的同源策略

同源策略是浏览器的一项安全策略,浏览器只允许js 代码请求和当前所在服务器域名,端口,协议相同的数据接口上的数据,这就是同源策略.

也就是说,当协议、域名、端口任意一个不相同时,都会产生跨域问题,所以又应该如何解决跨域问题呢?

以下是三种解决跨域问题的方法:

Jsonp --- 只能处理get请求,且不是ajax请求

jsonp跨域的原理是什么?

动态在页面中创建一个script标签,使其src属性指向后端数据接口,也就是说,script会发送一个get请求到src指向的地址,而这个src地址就是我们请求的服务接口。

其中callback参数就是核心所在,因为后端数据接口必须返回一个js函数的调用字符串(如cb('{"name":"zs","age":18)}')将要返回给前端的数作为函数的实参,当script标签加载完毕之后会在浏览器中执行后端返回的函数调用

这里必须使用script标签,否则返回的数据不会被当作js执行

借助script标签中的src 地址写入url地址并且用?拼接要传入的参数


  
  

这里可以看到,我们声明了一个func函数,但没有执行,如果服务端接口到get请求,返回的是func({message:'hello'}),这样的话在服务端就可以把数据通过函数执行传参的方式实现数据传递 

服务端代码:

router.get('/article-list', (req, res) => {
  console.log(req.query, '123');
  let data = {
    message: 'success!',
    name: req.query.name,
    age: req.query.age
  }
  data = JSON.stringify(data)
  res.end('func(' + data + ')');
});

Cors  ---  任意请求都可以解决,且发送的是ajax请求

在后台响应头中设置 res.setHeader("Access-Control-Allow-Origin","*")//*代表着任何一方的请求和响应

let queryString = require("querystring") //处理post请求的
let http=require("http")
let url=require("url")
let cors = require("cors")

http.createServer((req,res)=>{

    let {pathname}=url.parse(req.url,true)

    //判断请求路径是不是post  请求方式是不是POST
    if(pathname=="/post" && req.method=="POST"){
        let data=""
        // 每一次的传递
        req.on("data",msg=>{  //msg是回调函数的形式
            console.log(msg);
            data+=msg//拼接
        })
        console.log(data);
        // 全部传输完毕
        req.on("end",()=>{
            res.setHeader("content-type","application/json")//响应头

            res.setHeader("Access-Control-Allow-Origin","*")//*代表着任何一方的请求和响应
            let str={...queryString.parse(data),_d:Date.now()}
            console.log(queryString.parse(data));
            res.end(JSON.stringify(str),()=>{
                console.log("本次请求完毕",str);
            })
        })
    }
}).listen(3000,console.log("run..."))

服务器代理proxy 

以下代码一般解决跨域请求数据问题

module.exports = {

    devServer:{

        port:5520,  //前端端口号

        host:'localhost',  //主机名

        https:false,

        open:true,  //启动服务时自动打开浏览器



        // proxy是代理  其内容主要是为了解决*跨域问题*

        proxy:{

            // 替换所有以'/dev-api'开始的地址

            // process.env.VUE_APP_BASE_API 相当于 '/dev-api'(在常量中已经定义完成了)



            // 匹配以'/dev-api'开头的请求

            [process.env.VUE_APP_BASE_API]:{



                // 目标服务器:'http://localhost:3000'(就是后端接口)

                target:process.env.VUE_APP_SERVICE_URL,

                changOrigin:true,  //开启代理

                pathRewrite:{

                    /* 将'/dev-api'替换为空串''

                       将'http://localhost:8001/dev-api/db.json'

                       替换为'http://localhost:8001/db.json'

                    */

                    ['^'+process.env.VUE_APP_BASE_API]:''

                }

            }

        }

    },

    lintOnSave:false,  //关闭代码风格检查

    productionSourceMap:false   // 不生成.map文件

}

你可能感兴趣的