INSTALLED_APPS = ( ... 'corsheaders', ... ) ... MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10 ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... ] ... # cookies will be allowed to be included in cross-site HTTP requests CORS_ALLOW_CREDENTIALS = True # If True, the whitelist will not be used and all origins will be accepted CORS_ORIGIN_ALLOW_ALL = False # A list of origin hostnames that are authorized to make cross-site HTTP requests CORS_ORIGIN_WHITELIST = ( 'localhost:8888' )
显式设置cookie
1 2 3 4 5 6 7 8 9 10 11
# view.py deftest(request): if request.method == 'POST': data = { 'code': 0, 'msg': 'this is a test', 'data': 'POST' } rep = HttpResponse(json.dumps(data, cls=CJsonEncoder), content_type="application/json") rep.set_cookie('key', 'value') return rep
var ajax = new XMLHttpRequest(); var data1 = '{"arr":[1,2,3,4,5],"test":"name"}' var data2 = 'name=jack&age=998' // 使用post请求 ajax.open('post', 'http://localhost:8000/api/test/');
<formaction="http://localhost:8000/api/test/"method="post"> First name:<br> <inputtype="text"name="firstname"value="Mickey"><br> Last name:<br> <inputtype="text"name="lastname"value="Mouse"><br><br> <inputtype="submit"value="提交"> </form>
for (var i = 0; i < 10; i++) { console.log('i=', i); } console.log('输出', i); // 输出 10
for 循环定义了变量 i,通常我们只想这个变量 i 在循环内使用,但忽略了 i 其实是作用在外部作用域(函数或全局)的。所以循环过后也能正常打印出 i ,因为没有块的概念。
甚至连 try/catch 也没形成块作用域:
1 2 3 4 5 6
try { for (var i = 0; i < 10; i++) { console.log('i=', i); } } catch (error) {} console.log('输出', i); // 输出 10
解决方法1
形成块作用域的方法当然是使用 es6 的 let 和 const 了, let 为其声明的变量隐式的劫持了所在的块作用域。
1 2 3 4
for (let i = 0; i < 10; i++) { console.log('i=', i); } console.log('输出', i); // ReferenceError: i is not defined
将上面例子的 var 换成 let 最后输出就报错了 ReferenceError: i is not defined ,说明被 let 声明的 i 只作用在了 for 这个块中。
除了 let 会让 for、if、try/catch 等形成块,JavaScript 的 {} 也能形成块
1 2 3 4 5
{ let name = '曾田生' }
console.log(name); //ReferenceError: name is not defined
解决方法2
早在没 es6 的 let 声明之前,常用的做法是利用 函数也能形成作用域 这么个概念来解决一些问题的。
看个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14
function foo() { var result = [] for (var i = 0; i < 10; i++) { result[i] = function () { return i } } console.log(i)// i 作用在整个函数,for 执行完此时 i 已经等于 10 了 return result } var result = foo() console.log(result[0]()); // 输出 10 期望 0 console.log(result[1]()); // 输出 10 期望 1 console.log(result[2]()); // 输出 10 期望 2
这个例子出现的问题是执行数组函数最终都输出了 10, 因为 i 作用在整个函数,for 执行完此时 i 已经等于 10 了, 所以当后续执行函数 result[x]() 内部返回的 i 已经是 10 了。
利用函数的作用域来解决
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
function foo() { var result = [] for (var i = 0; i < 10; i++) { result[i] = function (num) { return function () { // 函数形成一个作用域,内部变量被私有化了 return num } }(i) } return result } var result = foo() console.log(result[0]()); // 0 console.log(result[1]()); // 1 console.log(result[2]()); // 2
上面代码 console.log(a); // undefined 就是因为编译阶段先对变量做了声明,先声明了个变量 a, 并默认赋值 undefined
1 2 3
var a; console.log(a); // undefined a = 1;
2、函数提升
函数同样也存在提升,这就是为什么函数能先调用后声明了
1 2 3 4
foo(); function foo() { console.log('---foo----'); }
注意:函数表达式不会被提升
1 2 3 4 5
foo(); var foo = function() { console.log('---foo----'); } // TypeError: foo is not a function
注意:函数会首先被提升,然后才是变量
1 2 3 4 5 6
var foo = 1; foo(); function foo() { console.log('---foo----'); } // TypeError: foo is not a function
分析一下,因为上面例子编译后是这样的
1 2 3 4 5 6 7
var foo = undefined; // 变量名赋值 undefined function foo() { // 函数先提升 console.log('---foo----'); } foo = 1; // 但接下去是变量被重新赋值了 1,是个Number类型 foo(); // Number类型当然不能用函数方式调用,就报错了 // TypeError: foo is not a function
function foo() { var a = 0; function bar() { a++; console.log(a); } return bar; }
var bat = foo() bat() // 1 bat() // 2 bat() // 3
结合例子分析一下: 函数 foo 内部返回了函数 bar ,外部声明个变量 bat 拿到 foo 返回的函数 bar ,执行 bat() 发现能正常输出 1 ,注意前面章节提到的作用域,变量 a 是在函数 foo 内部的一个私有变量,不能被外界访问的,但外部函数 bat 却能访问的到私有变量 a,这说明了 外部函数 bat 持有函数 foo 的作用域 ,也就产生了闭包。
function foo() { var _a = 0; var b = 0; function _add() { b = _a + 10 } function bar() { _add() } function getB() { return b } return { bar: bar, getB: getB } }