python django 使用记录

来源:互联网 发布:淘宝运费模块名称 编辑:程序博客网 时间:2024/06/05 06:58

主要想用web搭建个声纹识别的接口,目前正在学python,比较敏捷,django是其中使用广泛的文本框架,下面是使用过程中遇到的问题记录

1、任意ip访问

1)settings中

ALLOWED_HOSTS = ['*']

2)

python manage.py runserver 0.0.0.0:8000


2、js提交表达问题

Forbidden (403)
CSRF verification failed. Request aborted.
You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.
If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for 'same-origin' requests.


这个是csrf验证不通过,为什么需要csrf:

1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;

2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

3.用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;

4.网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;

5.浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

预防csrf攻击简单可行的方法就是在客户端网页上添加随机数,在服务器端进行随机数验证,以确保该请求是用户允许的。Django也是通过这个方法来防御csrf攻击的

参考链接 http://www.jianshu.com/p/a178f08d9389

解决办法:

1)

表单中加入{% csrf_token %}:

<form name="enrollForm" action="/enroll-audio-over"
                  onsubmit="return UploadRecord()" method="post">
                 {% csrf_token %}
                <div style="margin-top: 30px">
                    <input id="username" type="text" placeholder="????..." >
                    <input type="submit" value="????"/>
                </div>
 </form>

2)

不要用render,要使用render_to_response

3)

过滤csrf检验:@csrf_exempt


3、django中执行shell脚本并返回执行结果到页面上

    (status, output) = commands.getstatusoutput('echo "test shell"')
    context = {}
    context['status'] = status
    context['output'] = output
    return render(request, 'index.html', context)


4、onsubmit的bug,UploadRecord()的返回值不能影响表单的提交

<form name="enrollForm" action="/enroll-audio-over"
     onsubmit="return UploadRecord();" method="post">
    {% csrf_token %}
     <div style="margin-top: 30px">
          <input id="username" type="text" placeholder="你的姓名..." >
          <input type="submit" value="上传录音"/>
     </div>
</form>

在网上检索没找到合理的解释,自己分析的结果:如果UploadRecord()只是简单的检测输入的合理正确性,就没问题;如果其中做了网页的跳转或者提交服务器的操作就会有问题。

处理办法:避免在一个表单里做多个提交,可以直接用js响应按键的点击,然后再在按键的响应结束后做提交或跳



5、html5录音

感觉也是挺坑的,调用不同浏览器的接口,AudioAPI的默认采样频率是由实现定义,且不能修改的, Firefox使用44100(笔记本的是48000),而Chrome使用了最大采样比率96000,而每个采样位数获取不到:



所以想要修改其他的采样率就得在这个基础上下采样,想要更高的采样就不行了,下面是结合同事在网上找的代码再修改的,主要是声道数,及下采样的修改。

1.js

(function (window) {      window.URL = window.URL || window.webkitURL;      navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;        var HZRecorder = function (stream, config) {          config = config || {};        config.sampleBits = config.sampleBits || 16;             config.sampleRate = config.sampleRate || (8000);           // config.sampleBits = 16;      //???? 8, 16        // config.sampleRate = 8000;                  var audioContext = window.AudioContext            || window.webkitAudioContext  // Chrome            || window.mozAudioContext  // Firefox            || window.msAudioContext;        var context = new audioContext();          var audioInput = context.createMediaStreamSource(stream);                     var volume = context.createGain();          audioInput.connect(volume);             var bufferSize = 4096;            // 创建声音的缓存节点 第二和第三指输入和输出的声道数          // var recorder = context.createScriptProcessor(bufferSize, 2, 2);        var recorder = context.createScriptProcessor(bufferSize, 1, 1);        var audioData = {              size: 0          //录音文件长度             , buffer: []                   , inputSampleRate: context.sampleRate                , inputSampleBits: 16                   , outputSampleRate: config.sampleRate                , outputSampleBits: config.sampleBits                , input: function (data) {                  this.buffer.push(new Float32Array(data));                  this.size += data.length;              }            //先合并,在下采样            , compress: function () {                //  合并                 var data = new Float32Array(this.size);                  var offset = 0;                  for (var i = 0; i < this.buffer.length; i++) {                      data.set(this.buffer[i], offset);                      offset += this.buffer[i].length;                  }                                  //  下采样                var compression = (this.inputSampleRate / this.outputSampleRate);                var length = parseInt(data.length / compression);                var result = new Float32Array(length);                var index = 0;                while (index < length) {                    offset = parseInt(index * compression);                    result[index] = data[offset];                    index++;                }                return result;              }            , encodeWAV: function () {                  var sampleRate = Math.min(this.inputSampleRate, this.outputSampleRate);                  var sampleBits = Math.min(this.inputSampleBits, this.outputSampleBits);                var bytes = this.compress();                  var dataLength = bytes.length * (sampleBits / 8);                  var buffer = new ArrayBuffer(44 + dataLength);                  var data = new DataView(buffer);                    var channelCount = 1;                var offset = 0;                    var writeString = function (str) {                      for (var i = 0; i < str.length; i++) {                          data.setUint8(offset + i, str.charCodeAt(i));                      }                  };                                    // ?????????                   writeString('RIFF'); offset += 4;                  // ??????????????,?????-8                   data.setUint32(offset, 36 + dataLength, true); offset += 4;                  // WAV????                  writeString('WAVE'); offset += 4;                  // ??????                   writeString('fmt '); offset += 4;                  // ????,??? 0x10 = 16                   data.setUint32(offset, 16, true); offset += 4;                  // ???? (PCM??????)                   data.setUint16(offset, 1, true); offset += 2;                  // ???                   data.setUint16(offset, channelCount, true); offset += 2;                  // ???,?????,???????????                   data.setUint32(offset, sampleRate, true); offset += 4;                  // ??????? (???????) ???????????????/8                   data.setUint32(offset, channelCount * sampleRate * (sampleBits / 8), true); offset += 4;                  // ?????? ????????? ???????????/8                   data.setUint16(offset, channelCount * (sampleBits / 8), true); offset += 2;                  // ???????                   data.setUint16(offset, sampleBits, true); offset += 2;                  // ?????                   writeString('data'); offset += 4;                // ??????,??????-44                   data.setUint32(offset, dataLength, true); offset += 4;                  // ??????                   if (sampleBits === 8) {                      for (var i = 0; i < bytes.length; i++, offset++) {                          var s = Math.max(-1, Math.min(1, bytes[i]));                          var val = s < 0 ? s * 0x8000 : s * 0x7FFF;                          val = parseInt(255 / (65535 / (val + 32768)));                          data.setInt8(offset, val, true);                      }                  } else {                      for (var i = 0; i < bytes.length; i++, offset += 2) {                          var s = Math.max(-1, Math.min(1, bytes[i]));                          data.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);                      }                  }                    return new Blob([data], { type: 'audio/wav' });              }          };            //????          this.start = function () {              audioInput.connect(recorder);              recorder.connect(context.destination);          };            //??          this.stop = function () {              recorder.disconnect();          };            //??????          this.getBlob = function () {              this.stop();              return audioData.encodeWAV();          };            //??          this.play = function (audio) {              audio.src = window.URL.createObjectURL(this.getBlob());          };            //??          this.upload = function (url, username, callback) {            var fd = new FormData();              fd.append('userName', username);            fd.append('audioData', this.getBlob());            var xhr = new XMLHttpRequest();              if (callback) {                  xhr.upload.addEventListener('progress', function (e) {                      callback('uploading', e);                  }, false);                  xhr.addEventListener('load', function (e) {                    callback('????', e);                }, false);                  xhr.addEventListener('error', function (e) {                    callback('error', e);                }, false);                  xhr.addEventListener('abort', function (e) {                    callback('cancel', e);                  }, false);              }              xhr.open('POST', url);              xhr.send(fd);          };            //????          recorder.onaudioprocess = function (e) {              audioData.input(e.inputBuffer.getChannelData(0));              //record(e.inputBuffer.getChannelData(0));          };        };    //????      HZRecorder.throwError = function (message) {          throw new function () { this.toString = function () { return message; };};      };    //??????      HZRecorder.canRecording = (navigator.getUserMedia != null);    //?????      HZRecorder.get = function (callback, config) {          if (callback) {              if (navigator.getUserMedia) {                  navigator.getUserMedia(                      { audio: true } //?????                    , function (stream) {                          var rec = new HZRecorder(stream, config);                          callback(rec);                      }                    , function (error) {                          switch (error.code || error.name) {                              case 'PERMISSION_DENIED':                              case 'PermissionDeniedError':                                  HZRecorder.throwError('?????????');                                  break;                              case 'NOT_SUPPORTED_ERROR':                              case 'NotSupportedError':                                  HZRecorder.throwError('<a href="http://www.it165.net/edu/ewl/" target="_blank" class="keylink">???</a>????????');                                  break;                              case 'MANDATORY_UNSATISFIED_ERROR':                              case 'MandatoryUnsatisfiedError':                                  HZRecorder.throwError('????????????');                                  break;                              default:                                  HZRecorder.throwError('????????????:' + (error.code || error.name));                                  break;                          }                      });              } else {                  HZRecorder.throwErr('??<a href="http://127.0.0.1" target="_blank" class="keylink">???</a>????????'); return;            }          }    };      window.HZRecorder = HZRecorder;})(window);  
2.js
/* ?? */var recorder;  var audio = document.querySelector('audio');show = document.getElementById("show")var start = falsevar stop = truevar setIntervalHandler ;function startRecording() {    start = true;    recorderTime = 0;    function show1(){        recorderTime += 1;        show.innerHTML="?????..."+recorderTime+"?"    }    if (setIntervalHandler!=null){        clearInterval(setIntervalHandler)    }    setIntervalHandler = setInterval(show1,1000);    show.innerHTML="?????..."    HZRecorder.get(function (rec) {        recorder = rec;          recorder.start();      });  }  function obtainRecord(){      var record = recorder.getBlob();  };  function stopRecord(){    if(start == false){       show.innerHTML = "????";        return    }    clearInterval(setIntervalHandler)    stop = true    recorder.stop();    show.innerHTML = "?????";};    function playRecord(){    if(start == false){       show.innerHTML = "????";        return    }    clearInterval(setIntervalHandler)    show.innerHTML = "????";    stop = true    recorder.play(audio);};  function UploadRecord(){    if(start == false){        show.innerHTML = "????";        return false;    }    if(stop == false){        show.innerHTML = "??????"        return false;    }    clearInterval(setIntervalHandler)    var username = $("#username").val();    if (username == ""){        show.innerHTML = "?????"        return false;    }else{         recorder.upload("upload/", username, function (result) {             // show.innerHTML = result             // console.log(result)             // window.location = "index.html"             return true;         })         //return false;    }}

6、web audio api 手机端不能访问

需要使用https服务才可以

参考链接:http://www.jb51.net/article/51806.htm

在 CentOS 上

yum install stunnel

openssl req -new -x509 -days 365 -nodes -out vpsee.pem -keyout vpsee.pem

chmod 600 vpsee.pem

生成https文件:vi https

-----------------------

cert = vpsee.pem
debug = 7
foreground = yes

[https]
accept = 443
connect = 80
---------------------

启动服务:

stunnel https

django终端执行:

python manage.py runserver 0.0.0.0:80

然后就ok了。目前苹果手机及ie浏览器还跑不了