浏览器_跨域问题

目录

1.跨域报错

2.跨域现象产生的原因

[1].为什么要有同源策略?

3.如何解决跨域?

[1]CORS解决跨域(后端设置)

[2]JSPN解决跨域(前端+后端设置)

[3]使用代理来解决跨域(前端)


1.跨域报错

跨域会报一个固定格式的错误:

Access to XMLHttpRequest at 'ajax请求地址' has been blocked by CORS policy: No '网页请求地址' 'Access-Control-Allow-Or' present on the requested resource;

2.跨域现象产生的原因

  • ajax请求地址与页面请求地址不同源
    • 跨域只会出现在ajax请求,若是href、src是不会出现跨域问题的
    • ajax地址:获取数据的请求;
    • 页面请求地址:window.location.href;
  • 同源策略:若是协议、端口号、ip地址(域名) 全部一致被称为同源
    • 也就是说只要是协议、端口号、域名任何一个不一致则被称为不同源!
    • eg:页面地址为 http://127.0.0.1:3000/hero/add
      • ajax地址:https://127.0.0.1:3000/hero/all ---不同源(协议名不一致)
      • ajax地址:http://179.0.0.1:3000/hero/all ---不同源(域名不一致)
      • ajax地址:http://179.0.0.1:4399/hero/all ---不同源(端口号不一致)
      • ajax地址:https://127.0.0.1:3000/hero/add ---同源(与url路经无关)

[1].为什么要有同源策略?

其实同源策略存在的原因是浏览器为了保护电脑的安全:当ajax地址与页面请求地址不一样时,浏览器会认为你在向两台不同的服务器发送请求;此时浏览器会认为这个是不安全的,会将请求拦截。

3.如何解决跨域?

[1]CORS解决跨域(后端设置)

(1)后端设置白名单,也就是在响应头中设置一个标识,表示这个请求允许跨域;

(2)工作原理: 服务器 在返回响应报文的时候,在响应头中 设置一个允许的header

   res.setHeader('Access-Control-Allow-Origin', '*');

   这样这个ajax网址在发送请求的时候就不会出现跨域问题了!

(3)node中使用:因为存在多个请求,若是我们设置的话很麻烦而且会产生代码冗余;

解决:使用中间件在响应头的原型上添加允许跨域的属性setHeader;这样所有的请求(即使使用本地路经)都不会产生跨域问题了!

// 4.4允许跨域的中间件
const cors = require('cors')
app.use(cors())
// 原理给req的原型添加seHeader方法;

[2]JSPN解决跨域(前端+后端设置)

jsonp是早期解决跨域的方案;

(1)使用原理:浏览器漏洞

  • [1]跨域只存在于ajax请求,src是不会产生跨域的;
  • [2]如果script的src请求,服务器响应的数据是一个函数的调用,则浏览器会检查页面中是否存在此函数;
    • 页面中存在---调用;
    • 页面中不存在--报错 function is not defined

(2)项目中使用的工作流程

  • (1)在发送ajax请求的时候使用script标签的src属性来发送;
  • (2)在原有的参数后面追加一个参数 callback
    • 参数值为页面中声明的函数名;
  • (3)服务器返回一个函数的调用即可;
  • 举例说明(原生js)
    • [1]写一个html页面--发送请求的时候使用script标签的src属性
    •  <body>
          <script>
            function success (results) {
              console.log(results)
            }
          </script>
          <script src="http://127.0.0.1:3000/add?id=5&callback=success"></script>
        </body>

    • [2]使用node搭建服务器--若是url为/add,返回一个函数的调用,此时浏览器会去查找页面中是否有success方法,如是有的话则调用此函数;
      • 此时页面打印666
    • const express = require('express')
      
      const app = express()
      
      // 路由
      app.get('/add', (req, res) => {
        console.log(req.url)
        let { callback } = req.query
        // 假设响应结果为person对象
        let person = { name: 'chaochao', age: 20 }
      
        res.end(`${callback}(${JSON.stringify(person)})`)
      })
      app.post('/add', (req, res) => {
        console.log(req.url)
        res.end('success()')
      })
      app.listen(3000, () => {
        console.log('服务器开启成功')
      })
      

  • 举例说明(jquery)
    • $.ajax({
          url:'http://127.0.0.1:3000/add',
          dataType:'jsonp',
          data:{id:5},
          success:function(backData){
          conslole.log(backData)
       }
      })

    • 原理:jq在想使用jsonp时只需要将dataType的属性值由json变为jsonp即可;
      • 在发送请求的时候,jq会动态的在head中创建一个script标签用来发送请求;
      • 发送请求之后服务器返回success的调用;
      • 服务器响应数据之后,jq会自动删除创建的script标签;

[3]使用代理来解决跨域(前端)

  • 执行原理:

    • 因为跨域是在客户端与服务端产生的跨域,也就是说在服务端与服务端之间是不会产生跨域的;

    • 所以

      • [1]向浏览器同源的服务器发送请求;

      • [2]同源服务器再向实际不同源的服务器发送请求

    • 经过转换,就不会产生跨域问题了;

  • 使用场景

    • 只适用于开发环境,生产环境是没有办法使用的!

  • 代码

    • //vue-cli3.0 里面的 vue.config.js做配置
        module.exports = {
      devServer: {
        proxy: {
          '/public': {
            //这里最好有一个 /
            target: 'http://127.0.0.1/heimamm/public', // 后台接口域名
            secure: false, // 如果是https接口,需要配置这个参数
            changeOrigin: true, //是否跨域
            pathRewrite: {
              '/public': ''
            }
          }
        }
      }
        }
      ​
        // 只要碰到以/public开头的基地址,在发送请求时都会将基地址转化为target属性值+‘/public’
        //使用pathRewrite属性是将拼接的/public转化为空
      
      //注:在使用的时候将.env.development配置文件中的基地址换为/public
       

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值