【问题解决】前端学习踩坑记录

最近在学做前端,小白一枚,做个踩坑记录


20191021 更新:

此网站似乎使用 scroll-linked 定位效果。这可能无法与异步平移一起使用;

	<script>
		$(function(){
			 $(window).on("scroll",function(){
				var offset = $("html.body").scrollTop(); // 获取网页滚动偏移位
				if (offset>=100) {$("img").show(1000);}
				else {$("img").hide(1000);}
			});		
		});

	</script>

一个简单的通过监听页面滚动显示或隐藏图片的js,在Firefox中运行报错:

且无法实现图片展示与隐藏的效果。

解决方案:

	<script>
		$(function(){
			 $(window).on("scroll",function(){
				var offset = $(document).scrollTop(); // 获取网页滚动偏移位
				if (offset>=100) {$("img").show(1000);}
				else {$("img").hide(1000);}
			});		
		});

	</script>

虽然仍然会显示warning,但是可以实现滚动监听绑定的动画效果。可能的原因是Firefox定位滚轮移动距离的方式与其他浏览器不同。


20191029更新:

Forbidden (CSRF token missing or incorrect.): /xxx/xxx/

基于django后端框架下的ajax数据传输,如果需要保留django自带的CSRF验证,则需要在js脚本中加入

        $.ajaxSetup({
            data:{
                csrfmiddlewaretoken:'{{ csrf_token }}'
            }
        })

如果这个方法不行还可以试试这样写,前提页面中已经存在{% csrf_token %}:

               var csrfToken = $("[name='csrfmiddlewaretoken']").val();// 获取csrf_token
                $.ajax({
                    type: "POST",
                    url: "{% url 'space:change_profile' %}",
                    data: formData,
                    headers: {"X-CSRFToken": $.cookie('csrftoken')},
                    async: false,
                    cache: false,
                    contentType: false,
                    processData: false,
                    success: function(response){
                        alert(reponse.toString());
                    },
                    error: function(e){
                        alert('Network Failure');
                    }

即手动添加headers中的CSRF_Token信息。

当然所有的html中涉及POST请求的部分都要加入

{% csrf_token %}

例如一个简单的注册页面的表单部分:

            <form class="m-t" role="form" id="form" method="post" action="{% url 'main:register' %}" enctype="multipart/form-data">
                {% csrf_token %}
                <div class="form-group">
                    <label>学号</label>
                    <input type="text" name="uid" maxlength="20" placeholder="请输入您的学号" required id="id_uid" class="form-control">
                </div>
                <div class="form-group">
                    <label>用户名</label>
                    <input type="text" name="username" maxlength="20" placeholder="请设置您的用户名" required id="id_username" class="form-control">
                </div>
                <div class="form-group">
                    <label>密码</label>
                    <input type="password" name="password" maxlength="16" placeholder="请输入密码" required id="id_password" class="form-control">
                </div>
                <div class="form-group">
                    <label>再次输入密码</label>
                    <input type="password" name="password_rep" maxlength="20" placeholder="请再次输入密码" required id="id_password_rep" class="form-control">
                </div>
                <div class="form-group">
                    <label>名字</label>
                    <input type="text" name="first_name" maxlength="30" placeholder="请留下您的名字" id="id_first_name" class="form-control">
                </div>
                <div class="form-group">
                    <label>姓氏</label>
                    <input type="text" name="last_name" maxlength="30" placeholder="请留下您的姓氏" id="id_last_name" class="form-control">
                </div>
                <div class="form-group">
                    <label>头像</label>
                    <input type="file" name="profile" placeholder="点击选择您的头像" id="id_profile" class="form-control" onchange="verificationPicFile(this)">
                </div>
                <div>
                    <label>电子邮件地址</label>
                    <div class="row">
                        <div class="form-group col-md-8">
                            <input type="email" name="email" maxlength="40" placeholder="请设置您的验证邮箱" id="id_email" class="form-control">
                        </div>
                        <div class="form-group col-md-2 offset-1">
                            <button type="button" class="ladda-button btn btn-primary" id="send-email-button" data-style="zoom-in">Send</button>
                        </div>
                    </div>
                </div>
                <div>
                    <label>验证码</label>
                    <input type="text" name="code" maxlength="4" placeholder="请输入验证码" id="id_code" class="form-control">
                </div>
                <div class="form-group">
                    <div class="checkbox i-checks"><label> <input type="checkbox"><i></i> Agree the terms and policy </label></div>
                </div>
                <button type="submit" class="btn btn-primary block full-width m-b">Register</button>

20191029更新:

Django接收ajax传输的图片数据

JS部分:

                var csrfToken = $("[name='csrfmiddlewaretoken']").val();// 获取csrf_token
                $.ajax({
                    type: "POST",
                    url: "{% url 'space:change_profile' %}",
                    data: formData,
                    headers: {"X-CSRFToken": $.cookie('csrftoken')},
                    async: false,
                    cache: false,
                    contentType: false,
                    processData: false,
                    success: function(response){
                        alert(reponse.toString());
                    },
                    error: function(e){
                        alert('Network Failure');
                    }
                });

视图函数:

def change_profile(request):                                                                                             # 获取头像
    if request.method == "POST":
        profile = request.POST.get("profile")                                                                           # 获取用户设置的验证邮箱
        print("PROFILE的内容为",profile)
        return ajax_response("0", "Successfully reponsed", {"profile_token": 1})
    else:
        raise InvalidOperation("无效的请求")

发现后端始终无法获取到ajax传输到的图片,其实之前获取不到出的是另外一个问题就是:

urlpatterns = [
	url(r"^(?P<username>\w+)/$",views.center,name="center"),															# 用户中心页面
	url(r"^change_profile/",views.change_profile,name="change_profile"),												# 修改头像
]

当我URL如此配置时如果我修改用ajax将图片传至change_profile()视图函数,则会匹配到第一个name为center的URL中,原因是没有精准匹配。

修改了change_profile的URL为

urlpatterns = [
	url(r"^(?P<username>\w+)/$",views.center,name="center"),															# 用户中心页面
	url(r"^user/change_profile/",views.change_profile,name="change_profile"),												# 修改头像
]

后发现视图函数中获取到的图片始终为None,原因是图片没有保存在request.POST对象中,而是request.FILES中:

def change_profile(request):                                                                                             # 获取头像
    if request.method == "POST":
        profile = request.FILES.get("profile")                                                                           # 获取用户设置的验证邮箱
        print("PROFILE的内容为",profile)
        return ajax_response("0", "Successfully reponsed", {"profile_token": 1})
    else:
        raise InvalidOperation("无效的请求")

20191030更新

JS刷新图片元素

用户重新上传图片更新头像后,页面上的图片仍然没有发生变化。刷新页面后用户头像发生变化。我们当然不希望页面全部重新加载,而只希望相应的img标签重新加载。

我试着找了一些方法后发现没有特别靠谱的局部刷新图片的方法,一种可行的方法是在img标签的src属性值后添加一段随机值(如日期),则可以实现用户上传图片文件,后端修改服务器图片文件,前端页面立即更新到新的图片。

                var csrfToken = $("[name='csrfmiddlewaretoken']").val();// 获取csrf_token
                $.ajax({
                    type: "POST",
                    url: "{% url 'space:change_profile' username %}",
                    data: formData,
                    headers: {"X-CSRFToken": $.cookie('csrftoken')}, // 这里的值可以用csrfToken替代!否则需要预先导入jquery.cookie.js
                    async: false,
                    cache: false,
                    contentType: false,
                    processData: false,
                    success: function(response){// 成功修改则即刻更新图片
                        console.log("劳资来更新头像了。。。");
                        var profileSrc = $("img#showImg").attr("src");
                        var date = new Date()
                        $("img#showImg").attr("src",profileSrc+"?"+date.getTime());
                    },
                    error: function(e){
                        alert('Network Failure');
                    }
                });

20191101更新

$.ajax()中无法为全局变量赋值问题

        $("button.m-b").click(function(){
            var csrfToken = $("[name='csrfmiddlewaretoken']").val();
            var username = $("input[name='username']").val();
            var password = $("input[name='password']").val();
            var flag = false // 控制事件冒泡
            $.ajax({
                type: "POST",
                url: {% url 'main:validate_login_formdata' %},
                data: {'username': username, 'password': password},
                headers: {"X-CSRFToken": csrfToken},
                success: function(response){// 成功修改则即刻更新图片
                    response = JSON.parse(response);
                    if(response.code=='0') {
                        alert(response.msg);
                    }
                    else {
                        console.log("我也曾来过这里")
                        flag = true;}
                },
                error: function(e){
                    alert('Network Failure');
                }
            });
            console.log(flag)
            return flag;

一段控制提交按钮点击的ajax,希望在用户名密码不匹配时不发生事件冒泡(即return flag=false),而匹配时希望在success中修改flag从而使得返回值为true发生事件冒泡(页面跳转)。但是实际操作过程中flag始终都是false,页面始终不会跳转。

原因是同步加载,当$.ajax()中未设置async属性参数时,默认会先运行到return flag,然后才是$.ajax()中的内容,如果需要同步运行,需要设置async:false即可:

        $("button.m-b").click(function(){
            var csrfToken = $("[name='csrfmiddlewaretoken']").val();
            var username = $("input[name='username']").val();
            var password = $("input[name='password']").val();
            var flag = false // 控制事件冒泡
            $.ajax({
                type: "POST",
                url: {% url 'main:validate_login_formdata' %},
                data: {'username': username, 'password': password},
                headers: {"X-CSRFToken": csrfToken},
                async: false,
                success: function(response){// 成功修改则即刻更新图片
                    response = JSON.parse(response);
                    if(response.code=='0') {
                        alert(response.msg);
                    }
                    else {
                        console.log("我也曾来过这里")
                        flag = true;}
                },
                error: function(e){
                    alert('Network Failure');
                }
            });
            console.log(flag)
            return flag;

20191108更新

canvas画布标签之context.drawImage()函数不显示图片的问题:

最近在https://www.w3school.com.cn/tags/canvas_drawimage.asp上学习入门级的canvas标签使用,遇到了drawImage函数(亲自试一试https://www.w3school.com.cn/tiy/t.asp?f=html5_canvas_drawimage),看着它给的例子我整了半天没搞清楚这个函数要做什么,还以为是可以用鼠标在那个白板上画东西。

最后才弄明白是图片没展示出来所以是个白板,原因是在加载到JS中的ctx.drawImage时页面上的图片尚未加载完成,所以canvas上是个白板。解决办法是用windows.onload套住ctx.drawImage即可:

改自https://www.w3school.com.cn/tiy/t.asp?f=html5_canvas_drawimage

<!DOCTYPE html>
<html>
<body>

<p>要使用的图像:</p>
<img id="tulip" src="/i/eg_tulip.jpg" alt="The Tulip" />

<p>画布:</p>
<canvas id="myCanvas" width="500" height="300" style="border:1px solid #d3d3d3;background:#ffffff;">
Your browser does not support the HTML5 canvas tag.
</canvas>

<script>

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("tulip");
window.onload = function(){
  ctx.drawImage(img,10,10);
}
</script>

</body>
</html>

发布了40 篇原创文章 · 获赞 133 · 访问量 44万+

猜你喜欢

转载自blog.csdn.net/CY19980216/article/details/102671478
今日推荐