<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 跨域 跨域是指瀏覽器允許向服務器發送跨域請求,從而克服Ajax只能 `同源`使用的限制。 * 資源跳轉: A鏈接、表單提交 * ```<link>、<script>、<img>、<frame>等dom標簽,還有樣式中background:url()、@font-face()等文件外鏈``` * js發起的ajax請求,Fetch請求等 ### 同源策略 **同源策略**是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊。所謂同源是指"協議 + 域名 + 端口"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源。 #### 常見的跨域場景 | **URL** | **說明** | **通信** | | --- | --- | --- | | http://www.domain.com/a.js <br> http://www.domain.com/b.js| 同一域名,不同文件或路徑 | `允許`| | http://www.domain.com/a.js <br> https://www.domain.com/b.js| 同一域名,不同協議 | `不允許` | | http://www.domain.com/a.js <br> http://www.domain.com:8080/b.js | 同一域名,不同端口 | `不允許` | | http://www.domain.com/a.js <br> http://www.domain2.com/b.js | 不同域名,相同協議 |`不允許` | | http://www.domain.com/a.js <br> http://172.0.0.1/b.js | 域名和其對應的`ip` | `不允許` | | http://a.domain.com/a.js <br> http://b.domain.com/b.js | 不同子域名,相同主域名 |`不允許` | #### 跨域的解決方案 1. **JSONP跨域** **jsonp**的原理通過`<script>`標簽src屬性,發送帶有callback參數的`GET`請求,服務端將接口返回數據拼湊到callback函數中,返回給瀏覽器,瀏覽器解析執行,從而前端拿到callback函數返回的數據。 ``` // 回調函數 function handleEvent(data) { console.info(data) } // 原生js let script = document.createElement("script"); script.src = "https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=1432,21090,30211&wd=12&csor=2&pwd=1&cb=handleEvent&_=1576509650094"; document.body.insertBefore(script, document.body.firstChild) // Jquery $.ajax({ url: 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=1432,21090,30211&wd=12&csor=2&pwd=1&cb=handleEvent&_=1576509650094', type: 'get', dataType: 'jsonp', // 請求方式為jsonp jsonpCallback: "handleEvent", // 自定義回調函數名 data: {} }) ``` 2. **跨域資源共享(CORS)** 跨域資源共享(?[CORS](https://developer.mozilla.org/en-US/docs/Glossary/CORS "CORS: CORS (Cross-Origin Resource Sharing) is a system, consisting of transmitting HTTP headers, that determines whether browsers block frontend JavaScript code from accessing responses for cross-origin requests."))機制允許?Web 應用服務器進行跨域訪問控制,從而使跨域數據傳輸得以安全進行。 ##### **簡單請求** 對于簡單請求,瀏覽器會直接發出`CORS`請求,具體的就是在頭信息中,增加一個`Origin`字段。 1. 請求方法使用下列方法中的其中一個 * HEAD * GET * POST 2. HTTP頭信息不超過以下幾個字段 * Accept * Accept-Language * Content-Language * Last-Event-ID * Content-Type(只限于`application/x-www-form-urlencoded` | `multipart/form-data` | `text/plain`三個值) ``` # Reuqest Header // 本次請求來自哪個源(協議 + 域名 + 端口)。服務器根據這個值,決定是否同意這次請求。 Origin: https://www.cnblogs.com Host: constid.dingxiang-inc.com Accept-Language: zh-CN,zh;q=0.9 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79Safari/537.36 ``` ``` # Response Header // 服務器端指定允許其他域名訪問 Access-Control-Allow-Origin: https://www.cnblogs.com // 是否允許后續請求攜帶認證信息(cookies),該值只能是true,否則不返回 Access-Control-Allow-Credentials: true ``` ##### **非簡單請求** 非簡單請求是那種對服務器有特殊要求的請求,譬如`put` `delete`方法,或者`Content-Type`字段類型是`application/json`的,非簡單請求在正式通信前,會增加一次請求,稱為`預檢`請求,也就是`options`方法。 ##### **預檢請求** 瀏覽器先詢問服務器,當前網頁所在的域名是否在服務器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息字段。只有得到肯定答復,瀏覽器才會發出正式的`XMLHttpRequest`請求,否則就報錯。 ~~~http OPTIONS /cors HTTP/1.1 Origin: http://api.bob.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: magic Host: api.alice.com ~~~ 與簡單請求不同的是,option請求多了2個字段: `Access-Control-Request-Method`:必須字段,用來列出瀏覽器的CORS請求會用到哪些HTTP方法。 `Access-Control-Request-Headers`:該字段是一個逗號分隔的字符串,指定瀏覽器CORS請求會額外發送的頭信息字段。 ##### **預檢請求的回應** 服務器收到"預檢"請求以后,檢查了`Origin`、`Access-Control-Request-Method`和`Access-Control-Request-Headers`字段以后,確認允許跨源請求,就可以做出回應。 ~~~http Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Methods: GET, POST, PUT,Delete Access-Control-Allow-Headers: magic Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1728000 ~~~ **Access-Control-Allow-Origin** * `*`:設置`*`是最簡單粗暴的,但是服務器出于安全考慮,很少有人這么做,設置為`*`瀏覽器將不會發送`cookies`,即使你的`XHR`設置了`withCredentials`。(`Cookie`得有域名保存) * 指定域:后端指定一個固定的域。 * 請求域動態設置:后端維護一個固定的數組```[<域名1>, <域名2>...]```,使用`request origin`頭信息與數組做對比,來做請求域的設置。 **Access-Control-Allow-Methods** 表明服務器支持的所有跨域請求的方法。 **Access-Control-Allow-Headers** 表明服務器支持的所有頭信息字段,不限于瀏覽器在"預檢"中請求的字段。 **Access-Control-Allow-Credentials** 表示是否允許發送認證信息(Cookie)。 **Access-Control-Max-Age** 指定本次預檢請求的有效期,單位為秒,允許緩存。在緩存期間,不用發出另一條預檢請求。 3. **nginx代理跨域** ``` server { listen 80; server_name www.a.com; # img、css、js常規許可,這里主要針對的字體文件(eot|otf|ttf|woff|svg)相關 location / { add_header Access-Control-Allow-Origin *; } # 匹配以/apis/開頭的請求 location ^~ /apis/ { proxy_pass http://www.b.com; #反向代理 } } ``` 4. **nodejs中間件代理跨域** node中間件實現跨域代理,原理大致與nginx相同,都是通過啟一個代理服務器,實現數據的轉發。 **設置vue.config.js** **(只適合在 本地環境 使用)** ``` # devServer.proxy module.exports = { devServer:{ host: 'localhost',//target host port: 8080, //proxy:{'/api':{}},代理器中設置/api,項目中請求路徑為/api的替換為target proxy:{ '/api':{ target: 'http://192.168.1.30:8085',//代理地址,這里設置的地址會代替axios中設置的baseURL changeOrigin: true,// 如果接口跨域,需要進行這個參數配置 //ws: true, // proxy websockets secure: false, // 使用的是http協議則設置為false,https協議則設置為true //pathRewrite方法重寫url pathRewrite: { '^/api': '/' //pathRewrite: {'^/api': '/'} 重寫之后url為 http://192.168.1.16:8085/xxxx //pathRewrite: {'^/api': '/api'} 重寫之后url為 http://192.168.1.16:8085/api/xxxx } }, '/pay': { target: 'http://www.pay.com', ws: true, secure:false, changOrigin: true, } } } } ``` 5. **WebSocket協議跨域** WebSocket protocol是HTML5一種新的協議。它實現了瀏覽器與服務器全雙工通信,同時允許跨域通訊,是server push技術的一種很好的實現。原生WebSocket API使用起來不太方便,推薦使用Socket.io,它很好地封裝了webSocket接口,提供了更簡單、靈活的接口,也對不支持webSocket的瀏覽器提供了向下兼容。 ``` // 前端 <script src="https://cdn.bootcss.com/socket.io/2.3.0/socket.io.js"></script> // 與服務器端建立連接 const socket = io('http://www.domain2.com:8080') // 向服務器端發送信息 socket.emit('sentToServer', '你好,服務器!') // 3. 獲取服務端發送過來的信息 socket.on('sendToClient', message => { console.log(message); }) ``` ``` // 后端 let http = require('http') let io = require('socket.io') server.listen('8080'); console.log('Server is running at port 8080') // 監聽socket連接 io.listen(server).on('connection', function(socket) { // 接收信息 socket.on('sendToServer', function(msg) { console.log('data from client: ---> ' + msg); // 往客戶端發送信息 io.emit('sendToClient', '你好,客戶端!'); }) }) ``` 6. **postMessage跨域** 7. **document.domain + iframe跨域** 8. **location.hash + iframe跨域** 9. **window.name + iframe跨域** 10. **關閉瀏覽器的安全模式** * 找到chrome安裝目錄下的 `chrome.exe` 運行程序,以此創建快捷方式,建議把此快捷方式放到桌面; * 在電腦硬盤里創建一個空文件夾,并記錄此文件夾的路徑; * 右鍵 `chrome 快捷方式`,找到 `屬性` 欄目并點擊; * 在 `目標` 位置最后添加語句,` --disable-web-security --user-data-dir=空文件夾的路徑`; * 然后雙擊 `chrome 快捷方式` 你可以快樂的跨域了。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看