js跨域问题及解决方法汇总

这篇具有很好参考价值的文章主要介绍了js跨域问题及解决方法汇总。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

定义

浏览器为了保证用户信息的安全,防止恶意网站窃取数据,禁止不同域之间的js交互。对于浏览器而言,只要协议、域名、端口其中有一个不同就会触发同源策略,造成跨域,从而限制交互

  • cookie、storage、indexDB等不能获取

  • ajax不能发送请求、dom树无法获得

为什么要限制跨域访问

如果一个网页可以随意的访问另一个网站的资源,就有可能在用户完全不知情的情况下出现安全问题

浏览器出于安全问题,对同源请求放行,对异源请求限制,这些限制规则统称为同源策略,因为限制造成的开发问题,称之为跨域(异源)问题

对标签发出的跨域请求轻微限制,对 AJAX 发出的跨域请求严厉限制

方法

常用方法

跨域资源共享(CORS)

CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。

是一套机制,用于浏览器校验请求。只要服务器明确表示允许,则校验通过;服务器明确拒绝或没有表示,则校验不通过。CORS将请求分为两类,简单请求和预检请求:

简单请求
  1. 请求方法为GET、HEAD、POST

  1. 头部字段满足CORS安全规范

  1. 请求头的Content-Type为 text/plain、multipart/form-data、application/x-www-form-urlencoded

  1. 服务器响应头,要么同源,要么放行

预检请求
浏览器发送预请求
  1. 从哪个源发送的请求:Origin:http://my.com

  1. 请求方式:Access-Controt-Request-Method:POST

  1. 请求改变了哪些请求头:Access-Controt-Request-Headers:content-type

服务器进行响应
  1. Access-Controt-Allow-Origin:http://my.com...,允许的源,可以多个

  1. Access-Controt-Allow-Method:POST,GET...,允许的方式,可以多个

  1. Access-Controt-Allow-Headers:content-type...,允许改变的请求头,可以多个

  1. Access-Controt-Max-Age:86400,多少秒不用再次检验

jsonp

前端写一个函数,服务端调用函数传入参数,通过参数获取,根本不是AJAX

// 获取返回结果
function callback(resp){
    console.log(resp);
}

// 向服务端请求js文件
function request(url){
    // 生成一个 script 标签
    const script = document.createElement('script')
    // 标签引用 js 路径为填入路径
    script.src = url
    // 标签解析完成之后删除
    script.onload = function(){
        script.remove()
    }
    // 插入 body 中
    document.body.appendChild(script)
}

Nginx代理跨域

差别
  • cors:需要服务器设置响应头

  • jsonp:需要服务器响应一段js代码,并且还要调用函数

方法
  1. 浏览器请求自己的服务器 proxy

  1. 代理服务器请求目标服务器 target

  1. 服务器之间没有跨域问题,目标服务器响应代理服务器

  1. 代理服务器返回数据

// 引入库
const express = require('express')
// 创建服务器
const app = express()
// 接受对路径 /hero 的 GET 请求
app.get('/hero',async (req,res)=>{
    // 使用 cors 解决对代理服务器的跨域
    res.header('assess-control-allow-origin','*')
    // 响应一段测试文本
    res.send('你好,我是代理服务器')
    // 在这里请求目标服务器,然后返回给前端
})
// 监听9527端口
app.listen(9527,()=>{
    console.log('服务器已启动');
})

扩展学习

Node中间件代理跨域

Vue项目一般使用此方法,就是对代理服务器的一种封装。

在vue.config.js文件中配置
module.export = {
    ...
    devServer: {
        proxy: {
            [ process.env.VUE_APP_BASE_API ]: {
                target: 'http://xxxx',    // 代理跨域目标接口
                ws: true,
                changeOrigin: true,
                pathRewrite: {
                    [ '^' + process.env.VUE_APP_BASE_API ] : ''
                }
            }
        }
    }
Node/Express中配置:
const express = require(\'express\')
const proxy = require('http-proxy-middleware')
const app = express()
app.use('/', proxy({ 
    // 代理跨域目标接口 
    target: 'http:    // xxxx:8080', 
    changeOrigin: true, 
    // 修改响应头信息,实现跨域并允许带cookie 
    onProxyRes: function(proxyRes, req, res) { 
        res.header('Access-Control-Allow-Origin', 'http://xxxx')
        res.header('Access-Control-Allow-Credentials', 'true')
    }, 
    // 修改响应信息中的cookie域名 
    cookieDomainRewrite: 'www.domain1.com'     // 可以为false,表示不修改
})); 
app.listen(3000); 

Websocket

WebSocket是HTML5标准中的一种基于TCP但是区别于HTTP的通信协议,因为是长连接,该协议不实行同源政策。以ws://(非加密)和wss://(加密)作为协议前缀。

因为WebSocket请求头信息中有Origin字段,表示请求源来自哪个域,服务器可以根据这个字段判断是否允许本次通信。

// 创建websocket
var socket = new WebSocket('ws://www.baidu.com');
// 发送消息
socket.send('hello WebSocket');
// 接收消息
socket.onmessage = function(event){
    var data = event.data;
}

postMessage

是HTML5引入的一个全新的API:跨文档通信 API(Cross-document messaging)。 这个API为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。

窗口之间传递消息
// 父窗口发起
window.opener.postMessage("我是来自a页面的","http://b.com")

// 子窗口接收
window.onmessage = function(e){
    e = e || event;
    console.log(e.data);//我是来自a页面的
}
// 子窗口发送
window.opener.postMessage('我是来自b页面的', 'http://a.com');
读取其他窗口LocalStorage
// 父窗口调用方法
var obj = { name: 'Jack' };
// 存入对象
window.parent.postMessage(JSON.stringify({key: 'storage', method: 'set', data: obj}), 'http://b.com');
// 读取对象
window.parent.postMessage(JSON.stringify({key: 'storage', method: "get"}), "*");
window.onmessage = function(e) {
    // 判断消息是否来自a窗口
    if (e.origin != 'http://a.com') return;
    // "Jack"
    console.log(JSON.parse(e.data).name);
}

b窗口接收消息,获取自己的localStorage之后再传递给a窗口

window.onmessage = function(e) {
  // 消息来自自己,不予理会
  if (e.origin !== 'http://b.com') return;
  var payload = JSON.parse(e.data);
  // 判断方法进行操作
  switch (payload.method) {
    case 'set':
      localStorage.setItem(payload.key, JSON.stringify(payload.data));
      break;
    case 'get':
      var parent = window.parent;
      var data = localStorage.getItem(payload.key);
      // 如果是获取,获取之后传递给a窗口
      parent.postMessage(data, 'http://a.com');
      break;
    case 'remove':
      localStorage.removeItem(payload.key);
      break;
  }
}

单向跨域

利用浏览器对标签发出的跨域请求轻微限制,进行单方面的跨域请求

  • <img src='' />标签发送get请求

  • <script src=""></script>标签嵌入跨域脚本,语法错误信息只能在同源脚本中捕捉到。

  • <link src="">标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type消息头。

  • <video>、<audio>嵌入多媒体资源。

  • <object>、<embed>、<applet>的插件。

  • @font-face引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。

  • <iframe> 和 <iframe>载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。文章来源地址https://www.toymoban.com/news/detail-499800.html

到了这里,关于js跨域问题及解决方法汇总的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在uniapp Vue3版本中如何解决web/H5网页浏览器跨域的问题

    uniapp项目在浏览器运行,有可能调用某些接口会出现跨域问题,报错如下图所示: 存在跨域问题的原因是因为浏览器的同源策略,也就是说前端无法直接发起跨域请求。同源策略是一个基础的安全策略,但是这也会给uniapp/Vue开发者在部署时带来一定的麻烦。一般来说,浏览

    2024年01月21日
    浏览(38)
  • 2D-3D配准指南[方法汇总]【入门指导向】(一)问题介绍+LCD跨域描述子+Triplet loss

    近年来,采用三维和二维数据的应用层出不穷,它们都需要将 三维模型 与 二维图像 进行匹配。大型定位识别系统可以估算出照片拍摄的位置。在全球定位系统可能失灵的情况下,地理定位系统可以进行地点识别,对自动驾驶非常有用。此外,法医警察也可以利用该系统破案

    2024年02月03日
    浏览(33)
  • 浏览器同源策略导致跨域问题 No ‘Access-Control-Allow-Origin‘ header 原因及解决方式--(后端、nginx、前端)

    目录 现象 原因 浏览器同源策略 导致结果: 解决方案 跨源资源共享(CORS) 各个端解决方法: 后端: 方式1:重载WebMvcConfigurer方法 方式2:配置监听CorsFilter 方式3:相关类上加注解 @CrossOrigin 注意事项: Nginx解决: 情况1: 前端解决: 本人身份:后端 今天部署线上环境前端

    2024年01月23日
    浏览(44)
  • Node.js 使用 cors 中间件解决跨域问题

    cors 是 Express 的一个第三方中间件。通过安装和配置 cors 中间件,可以很方便地解决跨域问题。 CORS (Cross-Origin Resource Sharing,跨域资源共享)由一系列 HTTP 响应头 组成, 这些 HTTP 响应头决定浏览器是否阻止前端 JS 代码跨域获取资源 。 浏览器的 同源安全策略 默认会阻止网

    2024年01月20日
    浏览(35)
  • 前端跨域问题解决方法

    跨域是 WEB浏览器专有 的同源限制访问策略。(后台接口调用和postman等工具会出现) 跨源资源共享(CORS,或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资

    2024年02月13日
    浏览(32)
  • Nginx跨域问题的解决方法

    Web前端开发经常会遇到跨域访问,如果没有办法让后台开放访问域,调用接口就会被浏览器拦截。解决跨域问题的方案,可以搭建一个后台服务做中间转发,也可以用 nginx https://so.csdn.net/so/search?q=nginx 转发。 问题发生在nginx 反向代理 https://so.csdn.net/so/search?q=%E5%8F%8D%E5%90%91%E

    2024年02月11日
    浏览(35)
  • 解决跨域问题的常用方法

    有一个小小的东西叫cookie大家应该知道,一般用来处理登录等场景,目的是让服务端知道谁发出的这次请求。如果你请求了接口进行登录,服务端验证通过后会在响应头加入Set-C

    2023年04月08日
    浏览(20)
  • Spring Boot学习随笔- 后端实现全局异常处理(HandlerExceptionResolver),前后端解决跨域问题(@CrossOrigin(局部解决)自定义跨域配置类(全局))

    学习视频:【编程不良人】2021年SpringBoot最新最全教程 异常处理作用:用来解决整合系统中任意一个控制器抛出异常时的统一处理入口 传统单体架构下的处理方式 配置全局异常处理类 resolveException :当控制器方法出现异常时,如果该方法没有try...catch,则会进入当前方法 针

    2024年02月04日
    浏览(40)
  • vue自定义密码输入框解决浏览器自动填充密码的问题

    浏览器对于 type=\\\"password\\\" 的输入框会自动填充密码,但有时出于安全或者其他原因,我们不希望浏览器记住并自动填充密码。通过网上查到的一些解决方案,可以总结出以下几种解决方案(主要用edge浏览器进行测试): 通过 autocomplete=\\\"off\\\" / autocomplete=\\\"new-password\\\" 来关闭浏览器自

    2023年04月15日
    浏览(41)
  • 【Vue.js】Vue3全局配置Axios并解决跨域请求问题

    对于前后端分离项目,前端和后端端口不能重复,否则会导致前端或者后端服务起不来。例如前端访问地址为: http://localhost:8080/ ,后端访问地址为 http://localhost:8081/ 。后端写好Controller,当用Axios访问该接口时,将会报错: Access to XMLHttpRequest at \\\' http://localhost:8081/login \\\' from

    2024年02月05日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包