对几种与跨域相关的请求头做一个总结

关于跨域可以看:9 种常见的前端跨域解决方案(详解)

看完后可以配合我的代码做些实验,看看注释掉某个响应头会发生什么,整体代码会在最后贴出


1. 跨域简单请求

需要在服务器响应头中加 Access-Control-Allow-Origin

2. 跨域复杂请求

这时候会发送预检请求options,服务器需要在响应头中添加Access-Control-Allow-Headers来表明支持的请求头

需要响应头

  • Access-Control-Allow-Headers
  • Access-Control-Allow-Origin

响应头中 Access-Control-Allow-Headers 的值应该设置为是使简单请求变成非简单请求的请求头,有多个时则以逗号相连(当然,也可以设置为*)。在这里,因为发请求的时候我设置了

headers: {
"content-type": "application/json" //设置这个后,就不是简单跨域请求了
},

所以 Access-Control-Allow-Headers 响应头中至少要有 content-type

不加Access-Control-Allow-Headers则浏览器提示

Access to XMLHttpRequest at 'http://localhost:3333/test3' from origin 'http://localhost:2222' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

3. 跨域复杂请求,带 cookie

需要响应头

  • Access-Control-Allow-Headers,并且不能为 *
  • Access-Control-Allow-Origin,并且不能为 *
  • Access-Control-Allow-Credentials 为 true

4. 代码

分了三个文件

4.1. test.html

在这里发送 ajax 请求

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head> <body>
<button type="button" id="test1">不跨域请求</button>
<button type="button" id="test2">跨域简单请求</button> <button type="button" id="test3">跨域复杂请求</button>
<button type="button" id="test4">跨域复杂请求,带cookie</button>
<!-- <button type="button" id="test">测试</button> -->
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
var test1 = document.querySelector("#test1");
//不跨域请求
test1.addEventListener(
"click",
function() {
var url = `/test1`;
$.ajax({
url: url,
type: "get",
data: {
test: "test1"
},
success(res) {
var modal = `<div>不跨域请求成功:${res}</div>`;
$("body").append(modal); //htmlEscape()对字符进行转义,js不会被执行,而是作为字符串
}
});
},
false
); //跨域简单请求
var test2 = document.querySelector("#test2");
test2.addEventListener(
"click",
function() {
var url = `http://localhost:3333/test2`;
$.ajax({
url: url,
type: "post",
data: {
test: "test2"
},
success(res) {
var modal = `<div>跨域简单请求成功:${res}</div>`;
$("body").append(modal); //htmlEscape()对字符进行转义,js不会被执行,而是作为字符串
}
});
},
false
); // 跨域复杂请求
var test3 = document.querySelector("#test3");
test3.addEventListener(
"click",
function() {
var url = `http://localhost:3333/test3`;
$.ajax({
url: url,
type: "post",
headers: {
"content-type": "application/json" //设置这个后,就不是简单跨域请求了
},
data: {
test: "test3"
},
success(res) {
var modal = `<div>跨域复杂请求成功:${res}</div>`;
$("body").append(modal); //htmlEscape()对字符进行转义,js不会被执行,而是作为字符串
}
});
},
false
); // 带cookie的跨域请求
var test4 = document.querySelector("#test4");
test4.addEventListener(
"click",
function() {
var url = `http://localhost:3333/test4`;
$.ajax({
url: url,
type: "post",
headers: {
"content-type": "application/json" //设置这个后,就不是简单跨域请求了
},
xhrFields: {
withCredentials: true // 前端设置是否带cookie
},
data: {
test: "test4"
},
success(res) {
var modal = `<div>带cookie的跨域请求成功:${res}</div>`;
$("body").append(modal); //htmlEscape()对字符进行转义,js不会被执行,而是作为字符串
}
});
},
false
);
</script>
</body>
</html>

4.2. server.js

负责返回 test.html 和提供不跨域请求的接口

const fs = require("fs");
const http = require("http");
const qs = require("querystring");
const path = require("path"); http
.createServer((req, res) => {
let html = fs.readFileSync(path.resolve(__dirname, "./test.html"));
const url = req.url.split("?")[0];
const query = req.url.split("?")[1];
req.on("data", function(data1) {
postData += data1;
});
console.log("收到来自 ", url);
if (req.method == "GET") {
if (url == "/") {
//返回html模板
res.setHeader("set-cookie", "testCORS=riwang"); //设置cookie,后面发送带cookie的请求时使用
res.end(html);
} else if (url == "/test1") {
//不跨域请求
res.end(query);
}
}
})
.listen(2222);

4.3. api.js

负责提供跨域请求的接口

/*
* @Author: riwang
* @Date: 2020-03-23 23:30:59
* @LastEditTime: 2020-03-24 00:49:29
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \RW 笔记\web安全\跨域\code\api.js
*/ const fs = require("fs");
const http = require("http");
const qs = require("querystring");
const path = require("path"); http
.createServer((req, res) => {
let html = fs.readFileSync(path.resolve(__dirname, "./test.html")); const url = req.url.split("?")[0];
const query = req.url.split("?")[1];
const cookies = req.headers.cookie;
var postData = "";
req.on("data", function(data1) {
postData += data1;
});
console.log("收到来自 ", url);
if (req.method == "GET") {
res.end(html);
} else {
res.setHeader("set-cookie", "testCORS");
//跨域简单请求
if (url == "/test2") {
res.setHeader("Access-Control-Allow-Origin", "*"); req.on("end", function() {
res.end(postData);
});
} if (url == "/test3") {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "*");
req.on("end", function() {
res.end(postData);
});
} if (url == "/test4") {
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
res.setHeader("Access-Control-Allow-Headers", "content-type"); //这里设置为*浏览器会报错
res.setHeader("Access-Control-Allow-Credentials", true);
req.on("end", function() {
res.end(`postBody是${postData} |||||| cookies是${cookies}`);
});
}
}
})
.listen(3333);

关于CORS(跨域资源共享)的几个http请求头小实验的更多相关文章

  1. CORS跨域资源共享

    CORS(跨域资源共享)跨域问题及解决 当使用ajax跨域请求时,浏览器报错:XmlHttpRequest error: Origin null is not allowed by Access-Co ...

  2. CORS跨域资源共享你该知道的事儿

    "唠嗑之前,一些客套话" CORS跨域资源共享,这个话题大家一定不陌生了,吃久了大转转公众号的深度技术好文,也该吃点儿小米粥溜溜胃里的缝儿了,今天咱们就再好好屡屡CORS跨域资源共 ...

  3. 在ASP.NET Web API中实现CORS(跨域资源共享)

    默认情况下,是不允许网页从不同的域访问服务器资源的,访问遵循"同源"策略的原则. 会遇到如下的报错: XMLHttpRequest cannot load http://local ...

  4. django上课笔记7-jQuery Ajax 和 原生Ajax-伪造的Ajax-三种Ajax上传文件方法-JSONP和CORS跨域资源共享

    一.jQuery Ajax 和 原生Ajax from django.conf.urls import url from django.contrib import admin from app01 ...

  5. 跨域漏洞丨JSONP和CORS跨域资源共享

    进入正文之前,我们先来解决个小问题,什么是跨域? 跨域:指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器的安全限制! 跨域常见的两种方式,分别是JSONP和CORS. 今天i ...

  6. CORS跨域资源共享总结

    1.CORS简述 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源(协议 + 域名 + 端口)服务 ...

  7. Nginx CORS 跨域资源共享问题

    ## 背景 新项目上线,前后端分离,遇到了跨域资源共享的问题,导致请求根本无法发送到后端,前端和后端貌似只能有一个来处理跨域问题,我们这边要采用nginx来解决跨域问题. ## Nginx的CORS配 ...

  8. 浅谈跨域问题,CORS跨域资源共享

    1,何为跨域? 在理解跨域问题之前,你先要了解同源策略和URL,简单叙述: 1)同源策略 三同:协议相同,域名相同,端口相同: 目的:保证用户信息安全,防止恶意网站窃取数据.同源策略是必须的,否则co ...

  9. Node.js实现CORS跨域资源共享

    什么是CORS CORS(Cross-origin resource sharing),跨域资源共享,是一份浏览器技术的规范,用来避开浏览器的同源策略 简单来说就是解决跨域问题的除了jsonp外的另一 ...

随机推荐

  1. cesium入门示例-geoserver服务访问

    1.wms服务访问 //wms服务 viewer.imageryLayers.addImageryProvider(new Cesium.WebMapServiceImageryProvider({ ...

  2. SpringMVC之参数绑定

    1.Controller package com.tz.controller; import org.springframework.beans.factory.annotation.Required ...

  3. python爬取许多图片的代码

    from bs4 import BeautifulSoup import requests import os os.makedirs('./img/', exist_ok=True) URL = & ...

  4. OAuth 2.0学习笔记

    文章目录 OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务商提供商"进行互动. OAuth在"客户端&quo ...

  5. openCryptoki安装

    什么是OpenCryptoki OpenCryptoki提供Linux下的PKCS#11库和工具,支持包括TPM和IBM加密硬件以及软件令牌. 目前(2019/05/06)最新release版为3.1 ...

  6. Protobuf 简介及简单应用

    Protobuf 是 protocol buffers 的缩写. 根据官网的说法, protocol buffers 与平台无关, 与语言无关, 实现数据序列化的一种手段. 正如名字一样, proto ...

  7. Mac上各种实用命令

    下载Github资源:git clone 显示隐藏文件:defaults write com.apple.finder AppleShowAllFiles -bool true 隐藏隐藏文件:defa ...

  8. scss入门学习(一)

    sass的文件后缀名 sass是目前流行的css预处理语言.sass有两种后缀文件,一种是.sass,不允许使用大括号和分号:另一种是.SCSS,允许使用大括号和分号,类似于我们平时写css的语法习惯 ...

  9. IdentityServer4.FreeSql 持久化实现

    前言 故事是这样开始的: 然后突然又来了句... 扪心自问自从不知道怎么当了 FreeSql 开发群 () 的管理以来, 几乎没有给 FreeSql 做过什么贡献...惭愧惭愧. 借此机会, 似乎可以 ...

  10. C++走向远洋——57(项目二2、动物这样叫、抽象类)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...