window.status 在 firefox下生效

本文详细介绍了关于自定义配置(about:config)中的一项设置,即`dom_window_status_disabled`,如何将其从true更改为false以启用或禁用DOM窗口的状态栏显示。同时,文章深入剖析了这一操作对网页开发和用户体验的影响。

about:config  

dom_window_status_disabled  ->  false

function https(url,data,fu){ $.ajax({ contentType:"application/json", url: url, // 假设后端 API 地址 method: "POST", data: JSON.stringify(data), type: "json", dataType: "json", success:function(e){ console.log(e.data) if(e.status==200){ console.log(e.data) fu(e.data) }else{ alert(e.text) } }, error: function (e) { console.log(e.data) console.error(e) alert("请求失败,请稍后再试!"+e); } }); } function checkLoginStatus() { if (window.location.href.includes('/login.html')) return; } window.addEventListener('beforeunload', function(e) { console.trace('触发页面跳转的堆栈跟踪:'); }); //安全验证函数 function validateUserSession() { try { // 防御性数据获取 + 数据清洗 const rawValue = localStorage.getItem("name"); const username = String(rawValue ?? '') .trim() .replace(/[\u200B-\u200D\uFEFF]/g, ''); // 移除零宽字符 // 调试信息 console.log('[Auth] Raw:', rawValue, 'Processed:', username); // 复合验证条件 const isValid = ( username.length >= 2 && // 最小长度要求 !/[<>]/.test(username) && // 防止XSS username !== 'null' && username !== 'undefined' ); if (!isValid) { console.warn('无效用户标识:', username); // 安全跳转方法 //window.location.replace('/KuCun2/login.html'); // 立即终止执行 return Promise.reject('Invalid session'); } // 返回清洗后的用户名 return username; } catch (error) { console.error('会话验证失败:', error); // window.location.replace('/KuCun2/login.html'); return Promise.reject(error); } } function deepMergeArrays(frontend, backend) { const resultMap = new Map(); // 遍历前端数据并存入 Map 中以便快速查找 frontend.forEach(item => resultMap.set(item.id, { ...item })); // 遍历后端数据并与前端数据进行合并 backend.forEach(item => { if (resultMap.has(item.id)) { // 如果存在相同 ID,则合并两者的内容 resultMap.set( item.id, Object.assign(resultMap.get(item.id), item) ); } else { // 如果不存在相同 ID,则新增该条目 resultMap.set(item.id, { ...item }); } }); // 将最终结果转回数组形式 return Array.from(resultMap.values()); } (function ($){ // 页面加载时检查登录状态 checkLoginStatus(); })(jQuery); function removeSpecificCharactersAndConvertToNumber(str, charsToRemove) { const regex = new RegExp(`[${charsToRemove}]`, 'g'); // 创建用于匹配指定字符的正则表达式 const cleanedStr = str.replace(regex, ''); // 移除指定字符 const numberValue = parseFloat(cleanedStr); // 转换为浮点数 return isNaN(numberValue) ? null : numberValue; // 如果无法解析,则返回 null } <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>KuCun2</groupId> <artifactId>KuCun2</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>KuCun2</name> <description/> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> <!-- 请根据需要选择版本 --> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <webVersion>4.0</webVersion> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <protobuf.version>3.21.12</protobuf.version> </properties> <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>8.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.servlet.jsp.jstl</artifactId> <version>1.2.4</version> </dependency> <!-- Spring Boot Starter Data JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- MySQL Connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> <exclusions> <exclusion> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> </exclusion> </exclusions> </dependency> <!-- Optional: Lombok for reducing boilerplate code --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency> <!-- Jackson Databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <!-- Jackson Core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> <!-- Jackson Annotations --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </dependency> <dependency> <groupId>org.mindrot</groupId> <artifactId>jbcrypt</artifactId> <version>0.4</version> </dependency> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>${protobuf.version}</version> </dependency> <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.30</version> <!-- 统一版本号 --> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project> package com.kucun; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication( ) public class DemoApplication extends SpringBootServletInitializer { public static void main(String[] args) { // // ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args); // Arrays.stream(ctx.getBeanNamesForType(SecurityFilterChain.class)) // .forEach(System.out::println); // // // // 测试密码加密示例 // BCryptPasswordEncoder encoder = new BCrypt(); // String rawPassword = "987987"; // String encodedPassword = encoder.encode(rawPassword); // System.out.println("加密后的密码:" + encodedPassword); SpringApplication.run(DemoApplication.class, args); } }package com.kucun.Config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.kucun.Config.Role.RoleConverter; import com.kucun.Config.user.CustomUserDetails; import com.kucun.data.entity.User; import com.kucun.dataDo.UserRepository; /** * 获取数据 * @author Administrator * */ @Service public class CustomUserDetailsService/* implements UserDetailsService */{ // // @Autowired // private UserRepository userRepository; // // @Autowired // private RoleConverter roleConverter; // // public CustomUserDetailsService() { // // super(); // System.out.println("11111"); // } ///** // * 获取数据库中用户信息 // * @param andy 账号 // * // * @return // * // */ // @Override // public UserDetails loadUserByUsername(String andy) { // System.out.println(andy); // User user = userRepository.findByAndy(andy); // System.out.println(user); // return new CustomUserDetails(user, // roleConverter.convert(user.getRole()) // 关键转换点[^1] // ); // } }package com.kucun.Config; // 2. 基础安全配置 //@Configuration //@EnableWebSecurity // 启用Web安全功能 public class SecurityConfig //extends WebSecurityConfigurerAdapter { // @Override // public void configure(WebSecurity web) { // web.ignoring().antMatchers("/check-session"); // } // // 添加自定义Controller // @RestController // public static class SessionCheckController { // @GetMapping("/check-session") // public ResponseEntity<?> checkSession(HttpServletRequest request) { // return request.getSession(false) != null ? // ResponseEntity.ok().build() : // ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); // } // } // /** // * 核心安全过滤器链配置 // * @param http HTTP安全构建器 // * @return 安全过滤器链 // * @throws Exception 配置异常 // * // * █ 配置逻辑说明: // * 1. authorizeHttpRequests: 定义访问控制规则 // * 2. formLogin: 配置表单登录 // * 3. logout: 配置注销行为 // * 4. exceptionHandling: 处理权限异常[^3] // */ // // // 修正后的配置方法 // @Override // protected void configure(HttpSecurity http) throws Exception { // // // // http // .csrf().disable() // .sessionManagement() // .sessionCreationPolicy(SessionCreationPolicy.ALWAYS) // .invalidSessionUrl("/login.html?session=invalid") // .maximumSessions(1) // .maxSessionsPreventsLogin(false) // .and() // .and() // .addFilterBefore(jsonAuthFilter(), UsernamePasswordAuthenticationFilter.class) // 关键配置 // .authorizeRequests() // .antMatchers("/login.html", "/users/login").permitAll() // .antMatchers("/js/**", "/css/**", "/fonts/**", "/images/**","/check-session","/main/bootstrap-3.3.7-dist/**").permitAll() // .antMatchers("/users/guanli/**").hasAuthority("ROLE_ADMIN") // .anyRequest().authenticated() // .and() // .formLogin().disable() //// .loginPage("/login.html") //// .loginProcessingUrl("/users/login") //// //// .successHandler(ajaxAuthenticationSuccessHandler()) // 自定义成功处理器 //// .failureHandler(ajaxAuthenticationFailureHandler()) // 自定义失败处理器 //// .defaultSuccessUrl("/index.html") //// .failureUrl("/login.html?error=true") //// .usernameParameter("andy") // 修改用户名参数名 //// .passwordParameter("pass") // 修改密码参数名 //// .and() // // .logout() // .logoutUrl("/logout") // .logoutSuccessUrl("/login.html") // .and() // .csrf() // .ignoringAntMatchers("/users/login") // .and() // .headers() // .frameOptions().sameOrigin() // .and() // .exceptionHandling() // .accessDeniedHandler(accessDeniedHandler()); // 统一使用Handler // } // // // // // // // 返回JSON格式的成功响应 // @Bean // public AuthenticationSuccessHandler ajaxAuthenticationSuccessHandler() { // return (request, response, authentication) -> { // // // // // 强制创建服务端会话 // request.getSession(true); // // // // // String contextPath = request.getContextPath(); // HttpSession session = request.getSession(true); // Cookie cookie = new Cookie("JSESSIONID", session.getId()); // cookie.setPath(contextPath.isEmpty() ? "/" : contextPath + "/"); // cookie.setMaxAge(1800); // 30分钟 // response.addCookie(cookie); // // // //构建安全响应数据 // Map<String, Object> responseData = new HashMap<>(); // responseData.put("sessionId", request.getSession().getId()); // responseData.put("userInfo",Collections.unmodifiableMap(new HashMap<String, Object>() {/** // * // */ // private static final long serialVersionUID = 1L; // // { // put("Name", ((CustomUserDetails)authentication.getPrincipal()).getName()); // put("role", ((CustomUserDetails)authentication.getPrincipal()).getRole()); // }})); // // // // // 统一返回JSON格式 // response.setContentType(MediaType.APPLICATION_JSON_VALUE); // // new ObjectMapper().writeValue(response.getWriter(), responseData); // // // // // // // // // // response.setContentType(MediaType.APPLICATION_JSON_VALUE); // CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal(); // // response.setStatus(HttpStatus.OK.value()); // System.out.println(authentication.getPrincipal()+""+authentication.getName()); // // if (request.getHeader("X-Requested-With") == null) { // 非AJAX请求 // response.sendRedirect("/index.html"); // } else { // // //String re=userDetails.getUser().toString() // new ObjectMapper().writeValue(response.getWriter(), userDetails.getUser() // ); // // } // // // // // // // }; // } // // // 返回401状态码和错误信息 // @Bean // public AuthenticationFailureHandler ajaxAuthenticationFailureHandler() { // return (request, response, exception) -> { // if (request.getHeader("X-Requested-With") == null) { // response.sendRedirect("/login.html?error=true"); // } else { // response.setStatus(HttpStatus.UNAUTHORIZED.value()); // response.getWriter().write("{\"error\":\"Authentication failed\"}"); // } // }; // } // // // 处理未认证请求 // @Bean // public AuthenticationEntryPoint ajaxAuthenticationEntryPoint() { // return (request, response, exception) -> { // if (request.getHeader("X-Requested-With") == null) { // response.sendRedirect("/login.html?error=true"); // } else { // response.setStatus(HttpStatus.UNAUTHORIZED.value()); // response.getWriter().write("{\"error\":\"Authentication failed\"}"); // } // }; // } // // // // // // @Bean // public JsonUsernamePasswordAuthenticationFilter jsonAuthFilter() throws Exception { // // JsonUsernamePasswordAuthenticationFilter filter = // new JsonUsernamePasswordAuthenticationFilter(); // filter.setAuthenticationManager(authenticationManagerBean()); // filter.setUsernameParameter("andy"); // 设置自定义参数名 // filter.setPasswordParameter("pass"); // filter.setFilterProcessesUrl("/users/login"); // filter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler()); // filter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler()); // // return filter; // } // // // /** // * 密码编码器(必须配置) // * 使用BCrypt强哈希算法加密 // */ // @Bean // public PasswordEncoder passwordEncoder() { // return new BCryptPasswordEncoder(); // } // // // @Bean // public AccessDeniedHandler accessDeniedHandler() { // System.out.println("0000"); // return (request, response, ex) -> { // if (!response.isCommitted()) { // response.sendRedirect("/error/403"); // } // }; // } // // //} // // // // // // //class JsonUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { // private final ObjectMapper objectMapper = new ObjectMapper(); // // @Override // public Authentication attemptAuthentication(HttpServletRequest request, // HttpServletResponse response) // throws AuthenticationException { // System.out.println("收到认证请求,路径:" + request.getRequestURI()); // System.out.println("请求方法:" + request.getMethod()); // System.out.println("Content-Type:" + request.getContentType()); // if (request.getContentType() != null && // request.getContentType().startsWith(MediaType.APPLICATION_JSON_VALUE)) { // // try (InputStream is = request.getInputStream()) { // Map<String, String> authMap = objectMapper.readValue(is, Map.class); // // String username = authMap.getOrDefault(getUsernameParameter(), ""); // String password = authMap.getOrDefault(getPasswordParameter(), ""); // // // 调试日志 // System.out.println("Authentication attempt with: " + username+'_'+ password); // // UsernamePasswordAuthenticationToken authRequest = // new UsernamePasswordAuthenticationToken(username, password); // // setDetails(request, authRequest); // return this.getAuthenticationManager().authenticate(authRequest); // } catch (IOException e) { // throw new AuthenticationServiceException("认证请求解析失败", e); // } // } // Authentication aut= super.attemptAuthentication(request, response); // System.out.println("结果:"+aut.isAuthenticated()); // // return aut; // } } package com.kucun.Config.Role; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.json.Json; import org.springframework.stereotype.Component; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; /** * 权限转化 * @author Administrator * */ @Component public class RoleConverter { // private static final Map<Integer, String> ROLE_MAP = new HashMap<>(); // // @PostConstruct // public void init() { // ROLE_MAP.put(0, "ROLE_ADMIN"); // ROLE_MAP.put(1, "ROLE_USER"); // ROLE_MAP.put(2, "ROLE_MANAGER"); // ROLE_MAP.put(3, "ROLE_AUDITOR"); // } // // public List<GrantedAuthority> convert(int roleCode) { // ObjectMapper mapper = new ObjectMapper(); // try { // System.out.println(mapper.writeValueAsString(Collections.singletonList( // new SimpleGrantedAuthority(ROLE_MAP.getOrDefault(roleCode, "ROLE_GUEST")))).toString());//输出[{"authority":"ROLE_ADMIN"}] // } catch (JsonProcessingException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // // return Collections.singletonList( // new SimpleGrantedAuthority(ROLE_MAP.getOrDefault(roleCode, "ROLE_GUEST")) // ); // } // }package com.kucun.Config.user; import java.util.Collection; import com.kucun.data.entity.User; public class CustomUserDetails /*implements UserDetails*/ { // /** // * // */ // private static final long serialVersionUID = 1L; // private final String andy; // 对应andy字段 // private final String name; // private final int role; // private final String password; // private final User users; // private final Collection<? extends GrantedAuthority> authorities; // // public CustomUserDetails(User user, Collection<? extends GrantedAuthority> authorities) { // this.andy = user.getAndy(); // this.name = user.getName(); // this.role = user.getRole(); // this.password = user.getPass(); // user.setPass(null); // this.users=user; // this.authorities = authorities; // } // // // 实现UserDetails接口方法 // @Override public String getUsername() { return andy; } // @Override public String getPassword() { return password; } // @Override public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; } // // // 自定义字段访问方法 // public String getName() { return name; } // public User getUser() { return users; } // public int getRole() { return role; } // // // 其他必要方法 // @Override public boolean isAccountNonExpired() { return true; } // @Override public boolean isAccountNonLocked() { return true; } // @Override public boolean isCredentialsNonExpired() { return true; } // @Override public boolean isEnabled() { return true; } } <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <title>峤丞板材库存管理</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="fonts/font-awesome-4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" type="text/css" href="css/util.css"> <link rel="stylesheet" type="text/css" href="css/main.css"> <link rel="stylesheet" type="text/css" href="css/index2.css"> <style type="text/css"> *{ margin:0; padding:0; } .frame-header { height: 60px; background-color: #23262E; justify-content: space-between; } .frame-header-li{ font-family: Arial, Helvetica, sans-serif; font-size:40px; } .frame-ul{ } .frame-ul li{ border-style: solid; border-width:1px 0px 1px 0px; margin-top: 1px; height: 35px; text-align: center } #username{ position: absolute; right: 0; /* 靠右 */ } .frame-body { position: fixed; top: 60px; right: 0; bottom: 0; left: 0; display: flex; flex-direction: row; } .frame-side { scrollbar-width: none; /* firefox隐藏滚动条 */ -ms-overflow-style: none; /* IE 10+隐藏滚动条 */ overflow-x: hidden; overflow-y: auto; width: 200px; background-color:#9e5; } .frame-side::-webkit-scrollbar { display: none; /* Chrome Safari 隐藏滚动条*/ } .frame-main { flex-grow: 1; background-color:#fff; } .jiaoluo{ margin: auto; margin-right: 0px; } </style> </head> <body> <div class="frame-header"> <a class='frame-header-li' style="color:#fff">峤丞木材仓库管理</a> <a id="username" class='frame-header-li' style="color:#520">峤丞木材仓库管理</a> <button class=".menu-button" style="">注销</button> </div> <div class="frame-body"> <div class="frame-side"> <ul class='frame-ul' style="text-align:center;"> <li ><a href="main/test.html" target="main">首页</a></li> <li><a href="main/LuRul.html" target="main">材料录入</a></li> <li><a href="main/Guanli.html" target="main">材料录入</a></li> </ul> </div> <div class="frame-main"> <!-- 内容主体区域 --> <iframe id="iframeid" name="main" src="main/index.html" width="100%" height="100%" frameborder="0"> </iframe> </div> </div> </body> <script type="text/javascript" src="js/jquery-3.2.1.min.js"></script> <script type="text/javascript" src="js/jsyilai.js"></script> </html><!DOCTYPE html> <html lang="zh-CN"> <head> <title>扁平简洁的登录页面演示_dowebok</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="fonts/font-awesome-4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" type="text/css" href="css/util.css"> <link rel="stylesheet" type="text/css" href="css/main.css"> </head> <body> <div class="limiter"> <div class="container-login100"> <div class="wrap-login100"> <div class="login100-form-title" style="background-image: url(images/bg-01.jpg);"> <span class="login100-form-title-1">登 录</span> </div> <form class="login100-form validate-form"> <div class="wrap-input100 validate-input m-b-26" data-validate="用户名不能为空"> <span class="label-input100">用户名</span> <input class="input100" type="text" name="andy" placeholder="请输入用户名"> <span class="focus-input100"></span> </div> <div class="wrap-input100 validate-input m-b-18" data-validate="密码不能为空"> <span class="label-input100">密码</span> <input class="input100" type="password" name="pass" placeholder="请输入用户密码"> <span class="focus-input100"></span> </div> <div class="flex-sb-m w-full p-b-30"> <div class="contact100-form-checkbox"> <input class="input-checkbox100" id="ckb1" type="checkbox" name="remember-me"> <label class="label-checkbox100" for="ckb1">记住我</label> </div> <div> <a href="javascript:" class="txt1">忘记密码?</a> </div> </div> <div class="container-login100-form-btn"> <button class="login100-form-btn">登 录</button> </div> </form> </div> </div> </div> <script type="text/javascript"> </script> <script src="js/jquery-3.2.1.min.js"></script> <script type="text/javascript" src="js/jsyilai.js"></script> </body> </html> yilai.js (function ($) { var pathName = window.location.pathname; console.log(pathName); // 输出类似于 '/index.html' //alert(pathName) switch (pathName){ case "/KuCun2/login.html": jQuery.getScript('/KuCun2/js/main.js?'+Date.now()) jQuery.getScript('/KuCun2/js/login.js?'+Date.now()) break; case "/KuCun2/main/Guanli.html": jQuery.getScript('/KuCun2/js/main.js?'+Date.now()) jQuery.getScript('/KuCun2/js/guanli.js?'+Date.now()) jQuery.getScript('/KuCun2/main/bootstrap-3.3.7-dist/js/FileSaver.js?'+Date.now()) jQuery.getScript('/KuCun2/main/bootstrap-3.3.7-dist/js/MyTable.js?'+Date.now()) break; case "/KuCun2/index.html": jQuery.getScript('/KuCun2/js/main.js?'+Date.now()) jQuery.getScript('/KuCun2/js/index.js?'+Date.now()) break; } })(jQuery) main.js function https(url,data,fu){ $.ajax({ contentType:"application/json", url: url, // 假设后端 API 地址 method: "POST", data: JSON.stringify(data), type: "json", dataType: "json", success:function(e){ console.log(e.data) if(e.status==200){ console.log(e.data) fu(e.data) }else{ alert(e.text) } }, error: function (e) { console.log(e.data) console.error(e) alert("请求失败,请稍后再试!"+e); } }); } function checkLoginStatus() { if (window.location.href.includes('/login.html')) return; } window.addEventListener('beforeunload', function(e) { console.trace('触发页面跳转的堆栈跟踪:'); }); //安全验证函数 function validateUserSession() { try { // 防御性数据获取 + 数据清洗 const rawValue = localStorage.getItem("name"); const username = String(rawValue ?? '') .trim() .replace(/[\u200B-\u200D\uFEFF]/g, ''); // 移除零宽字符 // 调试信息 console.log('[Auth] Raw:', rawValue, 'Processed:', username); // 复合验证条件 const isValid = ( username.length >= 2 && // 最小长度要求 !/[<>]/.test(username) && // 防止XSS username !== 'null' && username !== 'undefined' ); if (!isValid) { console.warn('无效用户标识:', username); // 安全跳转方法 //window.location.replace('/KuCun2/login.html'); // 立即终止执行 return Promise.reject('Invalid session'); } // 返回清洗后的用户名 return username; } catch (error) { console.error('会话验证失败:', error); // window.location.replace('/KuCun2/login.html'); return Promise.reject(error); } } function deepMergeArrays(frontend, backend) { const resultMap = new Map(); // 遍历前端数据并存入 Map 中以便快速查找 frontend.forEach(item => resultMap.set(item.id, { ...item })); // 遍历后端数据并与前端数据进行合并 backend.forEach(item => { if (resultMap.has(item.id)) { // 如果存在相同 ID,则合并两者的内容 resultMap.set( item.id, Object.assign(resultMap.get(item.id), item) ); } else { // 如果不存在相同 ID,则新增该条目 resultMap.set(item.id, { ...item }); } }); // 将最终结果转回数组形式 return Array.from(resultMap.values()); } (function ($){ // 页面加载时检查登录状态 checkLoginStatus(); })(jQuery); function removeSpecificCharactersAndConvertToNumber(str, charsToRemove) { const regex = new RegExp(`[${charsToRemove}]`, 'g'); // 创建用于匹配指定字符的正则表达式 const cleanedStr = str.replace(regex, ''); // 移除指定字符 const numberValue = parseFloat(cleanedStr); // 转换为浮点数 return isNaN(numberValue) ? null : numberValue; // 如果无法解析,则返回 null } logi.js/// <reference path="jquery.d.ts" /> // $(document).ready(function(){ // $("#submit").click(function(){ // // // $.ajax({ // url:"../users/login", // async:false, // data:JSON.stringify({ // andy:$("#andy").val(), // pass:$("#pass").val(), // name:$("#name").val()}), // type:"post", // contentType:"application/json", // success:function(e){ // alert(e) // } // }); // // // }); // }) (function ($) { "use strict"; /*================================================================== [ Focus Contact2 ]*/ $('.input100').each(function () { $(this).on('blur', function () { if ($(this).val().trim() != "") { $(this).addClass('has-val'); } else { $(this).removeClass('has-val'); } }) }) /*================================================================== [ Validate ]*/ var input = $('.validate-input .input100'); $('.validate-form').on('submit', function (e) { e.preventDefault(); var check = true; for (var i = 0; i < input.length; i++) { if (validate(input[i]) == false) { showValidate(input[i]); check = false; } } confirm(input) if(check) login(input); return check; }); $('.validate-form .input100').each(function () { $(this).focus(function () { hideValidate(this); }); }); function validate(input) { if ($(input).attr('type') == 'email' || $(input).attr('name') == 'email') { if ($(input).val().trim().match(/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{1,5}|[0-9]{1,3})(\]?)$/) == null) { return false; } } else { if ($(input).val().trim() == '') { return false; } } } function showValidate(input) { var thisAlert = $(input).parent(); alert(input) $(thisAlert).addClass('alert-validate'); } function hideValidate(input) { var thisAlert = $(input).parent(); $(thisAlert).removeClass('alert-validate'); } // 登录按钮点击事件 function login(datas) { var data={} datas.each(function(a,element){ data[$(element).attr('name')]=$(element).val() }) alert(data.name); //var data={ andy,pass } // 模拟 AJAX 请求 https("/KuCun2/users/login",data,function (response) { alert("122222"); if (response.name) { localStorage.setItem("name", response.name); // 保存用户名到本地存储 localStorage.setItem("role", response.role); // 保存权限到本地存储 alert( response.name) window.location.href = '/KuCun2/index.html'; } else { alert("登录失败,请检查用户名和密码!"); } }) }; // 注销按钮点击事件 $("#logout-btn").click(function () { localStorage.removeItem("name"); // 清除本地存储中的用户名 checkLoginStatus(); // 更新登录状态 }); })(jQuery);index.js$().ready(function () { const username = localStorage.getItem("name"); $("#username").text(username) const $username = $('#username'); const $menuButton = $('.menu-button'); let hideTimeout = null; // 点击显示按钮 $username.on('click', function(e) { e.stopPropagation(); $menuButton.show(); }); // 区域外点击隐藏 $(document).on('click', function(e) { if (!$username.add($menuButton).is(e.target) && $username.has(e.target).length === 0 && $menuButton.has(e.target).length === 0) { $menuButton.hide(); } }); // 智能隐藏逻辑 const elements = $username.add($menuButton); elements.on('mouseleave', function() { hideTimeout = setTimeout(() => { $menuButton.hide(); }, 200); }).on('mouseenter', function() { clearTimeout(hideTimeout); }); var $iframe = $('<iframe>') // 使用 jQuery 监听 iframe 的 load 事件 $iframe.on('load', function() { try { // 确保 iframe 的内容可以被访问(非跨域情况下) var iframeDocument = $(this).contents(); var result = iframeDocument.find('body').text(); // 获取 iframe 内部的内容作为返回值 console.log("Iframe 加载完成后的返回值:", result); window.location.href="/KuCun2/login.html" } catch (error) { console.error("无法访问 iframe 内容,可能是因为跨域限制:", error.message); } }); // 将 iframe 添加到文档中 $('body').append($iframe); }); guanli.js(function ($) { //checkLoginStatus();//权限 https("/KuCun2/users/guanli/getusers",null,function(e){ $("#DataTable").remove() const c=[{id:" 序号 ", name:"名字", andy:"账号", role:"权限" }] let row = e.length+1; //c.concat(b); //const combinedArray = [c,e]; var r=deepMergeArrays(c,e) console.log(r ) let sclass = "table table-hover"; let bodys=[`<table id='DataTable' class='text-center ${sclass}'>`] let table=$("#TableView") table.append(bodys) let te= table.find("table") $.each(r, function(index, value) { var tr="" var boo=false if(index==0){var tr="<thead>"; boo=false} tr+="<tr>" $.each(value, function(name,val) { if(name!="pass"){ if(name!="id"){ tr+=`<td name='${name}' ><div contenteditable='${name!="id"&&boo}' style='float: left;width: 70%'>${val}</div></td>`; }else{ tr+=`<td name='${name}' style='float: left;width: 70%'>${val}</td>`; } } }) tr+="</tr>" if(index==0){ tr+="</thead>"} te.append(tr) }); addRight("#DataTable"); // // let sclass = "table table-striped"; // let bodys=[`<table id='DataTable' class='text-center ${sclass}'>`] // // for(let i = -1; i <= row; i++) { // bodys.push("<tr>"); // // if(i=-1){ // // for(var a in c[0]) { // // var bo= "<td><div contenteditable='true' style='float: left;width: 70%'>"+c[0][a]+"</div>"; // bodys.push(bo) // // } // // // }else{ // // // for(let j = 0; j <= col; j++) { // if(j == 0) { // var bo = "<td><div style='text-align: center;height: 100%'>" + e[i][b[j]] + "#</div></td>"; // bodys.push(bo) // } else { // var bo= "<td><div contenteditable='true' style='text-align: center;height: 100%'>" // + // // '<span class="glyphicon glyphicon-remove-sign" style="color: #999;font-size: 16px;" onclick="Deleterow(this)" aria-hidden="true"></span>' // +"</div></td>"; // bodys.push(bo) // } // } // } // bodys.push( "</tr>"); // // } // bodys.push("</table>"); // var s=bodys.join('') // $("#TableView").append(s); // addRight("#DataTable"); // }) })(jQuery) 访问index.html会被重定向到login.html其他以页面不回
05-31
还是没解析到目标数据啊,什么原因呢?这是我的代码: #!/usr/bin/env python # -*- coding: utf-8 -*- import requests import json import time import random import re from datetime import datetime from urllib.parse import quote, urlparse, parse_qs import logging import browser_cookie3 # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(f"instagram_fixed_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"), logging.StreamHandler() ] ) logger = logging.getLogger('InstagramFixed') class InstagramSessionFixer: def __init__(self, target_url): self.target_url = target_url self.post_shortcode = self.extract_shortcode(target_url) self.session = requests.Session() self.user_agents = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0' ] # 更新会话cookies self.cookies = { 'ds_user_id': '61971702457', 'csrftoken': '4YzNalzWguviI-qNJs0ftx', 'ig_did': '2661FC9A-4FB7-4383-B1EB-714C7A6A54E8', 'dpr': '1.25', 'mid': 'aQRkcwALAAHwafiIiIA8Jae8jgv1', 'ps_l': '1', 'ps_n': '1', 'sessionid': '61971702457%3ATzxhAREIa44MuZ%3A8%3AAYiF0jwFfuAmow6DcWxvsuow1VMgOTvnFfnf-S89PE8', 'wd': '1536x319', 'rur': '"CLN\\05461971702457\\0541793762034:01fe97acad5ea153bccfffef275c80d52863f3d5533563761ada96005c16b0ba99a4a9b5"', } # 添加Instagram所需的其他关键cookie self.cookies['ig_nrcb'] = '1' # 更新关键参数(最新的query_hash) self.post_query_hash = "37479f2b8209594dde7facb0d904896a" self.session.cookies.update(self.cookies) self.update_headers() self.attempt_count = 0 def extract_shortcode(self, url): pattern = r"https?://(?:www\.)?instagram\.com/p/([^/?#]+)" match = re.search(pattern, url) return match.group(1) if match else None def update_headers(self): # https://www.instagram.com/p/DP1z9ZUDiAL/?igsh=ajBqN282aWtxaXZv self.headers = { 'User-Agent': random.choice(self.user_agents), 'X-IG-App-ID': '936619743392459', 'X-Requested-With': 'XMLHttpRequest', 'Referer': f'https://www.instagram.com/p/{self.post_shortcode}/', 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'X-CSRFToken': self.cookies.get('csrftoken', ''), 'X-IG-WWW-Claim': 'hmac.AR2d7q7Yf4zE1HjzB8DlUcX0nqI9o9cVkQr1SQV7w8XqE3JxZf', 'Connection': 'keep-alive', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'TE': 'trailers', 'priority': 'u=0, i', 'upgrade-insecure-requests': '1' } def refresh_csrf_token(self): csrf_url = "https://www.instagram.com/" response = self.session.get(csrf_url, headers=self.headers) if 'csrftoken' in response.cookies: self.cookies['csrftoken'] = response.cookies['csrftoken'] self.session.cookies.update(self.cookies) self.headers['X-CSRFToken'] = self.cookies['csrftoken'] logger.info("CSRF令牌已刷新") def validate_session(self): """验证当前会话是否有效""" test_urls = [ "https://www.instagram.com/api/v1/users/web_profile_info/?username=instagram", "https://www.instagram.com/api/v1/feed/reels_tray/" ] for url in test_urls: try: response = self.session.get(url, headers=self.headers, timeout=10) if response.status_code == 200 and response.json().get('status') == 'ok': logger.info("会话验证成功") return True except: continue logger.warning("所有会话验证请求均失败") return False def get_browser_cookies(self, browser_type='chrome'): try: if browser_type == 'chrome': cookies = browser_cookie3.chrome(domain_name='.instagram.com') elif browser_type == 'firefox': cookies = browser_cookie3.firefox(domain_name='.instagram.com') elif browser_type == 'edge': cookies = browser_cookie3.edge(domain_name='.instagram.com') else: cookies = browser_cookie3.load(domain_name='.instagram.com') # 将浏览器cookies添加到会话 for cookie in cookies: self.session.cookies.set(cookie.name, cookie.value) # 更新本地cookie字典 self.cookies[cookie.name] = cookie.value logger.info(f"成功从{browser_type}导入{len(cookies)}个cookies") # 刷新CSRF令牌 self.refresh_csrf_token() return True except Exception as e: logger.error(f"导入浏览器cookies失败: {str(e)}") return False def safe_request(self, url): self.attempt_count += 1 # 每3次尝试刷新CSRF令牌 if self.attempt_count % 3 == 0: self.refresh_csrf_token() logger.info("已刷新请求头部") # 随机延迟 delay = random.uniform(1.5, 3.5) logger.info(f"请求前等待 {delay:.1f}秒...") time.sleep(delay) try: response = self.session.get(url, headers=self.headers, timeout=30) logger.debug(f"响应状态码: {response.status_code}") logger.debug(f"响应头: {response.headers}") if response.status_code == 200: logger.info("请求成功 (200 OK)") return response.json() elif response.status_code == 401: logger.error("会话已过期 (401 Unauthorized)") # 尝试自动修复会话 if self.get_browser_cookies(): return self.safe_request(url) # 重试 elif response.status_code == 403: logger.error("访问被拒绝 (403 Forbidden)") # 尝试刷新CSRF self.refresh_csrf_token() return self.safe_request(url) # 重试 elif response.status_code == 404: logger.error("资源不存在 (404 Not Found)") else: logger.error(f"请求失败: {response.status_code} {response.reason}") return None except requests.exceptions.RequestException as e: logger.error(f"请求异常: {str(e)}") return None def get_html_content(self): """直接获取页面HTML内容""" url = f"https://www.instagram.com/p/{self.post_shortcode}/" try: response = self.session.get(url, headers=self.headers) if response.status_code == 200: logger.info("成功获取HTML内容") return response.text else: logger.error(f"获取HTML失败: {response.status_code}") except Exception as e: logger.error(f"获取HTML失败: {str(e)}") return None def get_post_data(self): if not self.post_shortcode: logger.error("无效的Instagram URL") return None # 验证会话 if not self.validate_session(): logger.warning("会话无效,尝试从浏览器导入cookies...") self.get_browser_cookies() # 尝试REST API rest_api_url = f"https://www.instagram.com/p/{self.post_shortcode}/?__a=1&__d=dis" logger.info(f"尝试REST API端点: {rest_api_url}") rest_data = self.safe_request(rest_api_url) if rest_data and 'graphql' in rest_data: parsed_data = self.parse_rest_data(rest_data) if parsed_data: return parsed_data # 构造GraphQL请求 logger.warning("REST API失败,尝试GraphQL端点") variables = { "shortcode": self.post_shortcode, "child_comment_count": 3, "fetch_comment_count": 40, "parent_comment_count": 24, "has_threaded_comments": True } json_str = json.dumps(variables) encoded_str = quote(json_str) graphql_url = f"https://www.instagram.com/graphql/query/?query_hash={self.post_query_hash}&variables={encoded_str}" logger.info(f"请求GraphQL: {graphql_url[:100]}...") graphql_data = self.safe_request(graphql_url) if graphql_data and 'data' in graphql_data: parsed_data = self.parse_graphql_data(graphql_data) if parsed_data: return parsed_data else: logger.error("GraphQL请求失败") # 尝试直接访问页面作为最后手段 logger.warning("所有API失败,尝试直接解析HTML") html_data = self.get_html_content() if html_data: parsed_data = self.parse_html_data(html_data) if parsed_data: return parsed_data logger.error("所有方法均无法获取帖子数据") return None def parse_rest_data(self, json_data): """解析REST API返回的数据""" try: media = json_data.get('graphql', {}).get('shortcode_media') if not media: logger.error("REST响应中缺少shortcode_media") return None post_data = { 'id': media['id'], 'shortcode': media['shortcode'], 'likes_count': media['edge_media_preview_like']['count'], 'comments_count': media['edge_media_to_comment']['count'], 'timestamp': datetime.fromtimestamp(media['taken_at_timestamp']).strftime('%Y-%m-%d %H:%M:%S'), 'owner': media['owner']['username'], 'is_video': media['is_video'], 'caption': media['edge_media_to_caption']['edges'][0]['node']['text'] if media['edge_media_to_caption']['edges'] else '', 'shares_count': media.get('edge_web_media_to_related_media', {}).get('count', 0) } logger.info(f"解析成功 (REST): {post_data['shortcode']}") return post_data except KeyError as e: logger.error(f"解析失败 (REST): 缺少键 {e}") logger.debug(f"响应数据: {json.dumps(json_data, indent=2)}") return None def parse_graphql_data(self, json_data): """解析GraphQL返回的数据""" try: # 增强空值检查 if not json_data or 'data' not in json_data or not json_data['data']: logger.error(f"GraphQL返回无效数据: {json.dumps(json_data)[:200] if json_data else 'None'}") return None # 使用get方法安全访问嵌套属性 media = json_data.get('data', {}).get('shortcode_media') if not media: logger.error(f"GraphQL响应缺少shortcode_media: {json.dumps(json_data)[:200]}") return None # 安全访问其他属性 caption = "" if media.get('edge_media_to_caption', {}).get('edges'): caption = media['edge_media_to_caption']['edges'][0]['node']['text'] post_data = { 'id': media.get('id', ''), 'shortcode': media.get('shortcode', ''), 'likes_count': media.get('edge_media_preview_like', {}).get('count', 0), 'comments_count': media.get('edge_media_to_comment', {}).get('count', 0), 'timestamp': datetime.fromtimestamp(media.get('taken_at_timestamp', time.time())).strftime('%Y-%m-%d %H:%M:%S'), 'owner': media.get('owner', {}).get('username', ''), 'is_video': media.get('is_video', False), 'caption': caption, 'shares_count': media.get('edge_web_media_to_related_media', {}).get('count', 0) } logger.info(f"解析成功 (GraphQL): {post_data['shortcode']}") return post_data except Exception as e: logger.error(f"解析GraphQL数据时出错: {str(e)}") logger.debug(f"完整响应数据: {json.dumps(json_data, indent=2)[:500]}") return None def parse_html_data(self, html): """直接解析HTML页面内容获取数据""" try: # 方法1: 尝试从脚本标签提取结构化JSON数据 script_pattern = r'<script type="text/javascript">window\.__additionalDataLoaded\(\'[^\']+\',(.*?)\);</script>' script_match = re.search(script_pattern, html, re.DOTALL) if script_match: script_data = script_match.group(1).strip() if script_data.endswith(';'): script_data = script_data[:-1] try: json_data = json.loads(script_data) media = json_data.get('graphql', {}).get('shortcode_media') if media: # 复用已有的解析逻辑 post_data = { 'id': media.get('id', self.post_shortcode), 'shortcode': media.get('shortcode', self.post_shortcode), 'likes_count': media.get('edge_media_preview_like', {}).get('count', 0), 'comments_count': media.get('edge_media_to_comment', {}).get('count', 0), 'timestamp': datetime.fromtimestamp(media['taken_at_timestamp']).strftime('%Y-%m-%d %H:%M:%S') if 'taken_at_timestamp' in media else '', 'owner': media.get('owner', {}).get('username', ''), 'is_video': media.get('is_video', False), 'caption': media.get('edge_media_to_caption', {}).get('edges', [{}])[0].get('node', {}).get('text', ''), 'shares_count': media.get('edge_web_media_to_related_media', {}).get('count', 0) } logger.info("从HTML脚本中成功解析结构化数据") return post_data except json.JSONDecodeError as e: logger.warning(f"HTML中的JSON解析失败: {str(e)}") except KeyError as e: logger.warning(f"HTML JSON结构缺少键: {str(e)}") # 方法2: 备用方法 - 直接正则提取关键字段 logger.info("尝试备用HTML解析方法") # 提取点赞数 likes_match = re.search(r'"likeCount":(\d+)', html) or re.search(r'"likes":\s*{\s*"count":\s*(\d+)', html) # 提取评论数 comments_match = re.search(r'"commentCount":(\d+)', html) or re.search(r'"comments":\s*{\s*"count":\s*(\d+)', html) # 提取分享数 shares_match = re.search(r'"shareCount":(\d+)', html) or re.search(r'"shares":\s*{\s*"count":\s*(\d+)', html) # 提取作者 owner_match = re.search(r'"owner":\s*{\s*"username":\s*"([^"]+)"', html) or re.search(r'"owner_username":\s*"([^"]+)"', html) # 提取时间戳 timestamp_match = re.search(r'"uploadDate":\s*"([^"]+)"', html) or re.search(r'"taken_at_timestamp":\s*(\d+)', html) # 提取描述 caption_match = re.search(r'"caption":\s*"((?:[^"\\]|\\.)*)"', html) if caption_match: # 处理转义字符 caption = caption_match.group(1).encode('utf-8').decode('unicode_escape') else: caption = '' # 提取视频标志 is_video = bool(re.search(r'"is_video":\s*true', html)) or bool(re.search(r'"video_url":\s*"', html)) # 处理时间戳格式 timestamp_str = '' if timestamp_match: if timestamp_match.group(1).isdigit(): timestamp = datetime.fromtimestamp(int(timestamp_match.group(1))) timestamp_str = timestamp.strftime('%Y-%m-%d %H:%M:%S') else: timestamp_str = timestamp_match.group(1) post_data = { 'id': self.post_shortcode, 'shortcode': self.post_shortcode, 'likes_count': int(likes_match.group(1)) if likes_match else 0, 'comments_count': int(comments_match.group(1)) if comments_match else 0, 'shares_count': int(shares_match.group(1)) if shares_match else 0, 'timestamp': timestamp_str, 'owner': owner_match.group(1) if owner_match else 'unknown', 'is_video': is_video, 'caption': caption } logger.info("备用HTML解析方法成功") return post_data except Exception as e: logger.error(f"HTML解析失败: {str(e)}") logger.debug(f"HTML片段:\n{html[:1000]}") return None def print_results(self, post_data): if not post_data: logger.warning("没有数据可展示") return print("\n" + "=" * 50) print(f"Instagram 帖子分析结果: {self.target_url}") print("=" * 50) print(f"帖子ID: {post_data.get('id', '')}") print(f"发布时间: {post_data.get('timestamp', '')}") print(f"发布者: @{post_data.get('owner', '')}") print("-" * 50) print(f"点赞数: {post_data.get('likes_count', 0):,}") print(f"评论数: {post_data.get('comments_count', 0):,}") print(f"转发/分享数: {post_data.get('shares_count', 0):,}") print("=" * 50) print(f"内容描述: {post_data.get('caption', '')[:200]}...") print("=" * 50) def main(): # 目标帖子URL post_url = "https://www.instagram.com/p/DP1z9ZUDiAL/?igsh=ajBqN282aWtxaXZv" # 创建修复后的会话实例 fixer = InstagramSessionFixer(post_url) # 获取帖子数据 post_data = fixer.get_post_data() # 打印结果 if post_data: fixer.print_results(post_data) else: logger.error("无法获取帖子数据,请检查cookies和网络连接") if __name__ == '__main__': main()
11-05
postman调本地接口不行,返回<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>login</title> <meta name="format-detection" content="telephone=no,email=no,address=no"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="Expires" content="0"> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-control" content="no-cache"> <meta http-equiv="Cache" content="no-cache"> <meta name="referrer" content="same-origin"> <meta name="google" content="notranslate"> <style> .tipMessageBox { position: fixed; display: flex; font-size: 1.25rem; justify-content: center; color: #666; text-align: center; padding: 2rem; z-index: 9999; border-radius: 0.5rem; background: rgba(239, 239, 240, 0.8); top: 30%; margin-left: calc(50% - 13rem); } </style> <script> // 判断当前是否为支持的浏览器 function getExploreName() { const userAgent = navigator.userAgent; if (userAgent.indexOf('Opera') > -1 || userAgent.indexOf('OPR') > -1) { return 'Opera'; } if (userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1) { return 'IE'; } if (userAgent.indexOf('Edge') > -1) { return 'Edge'; } if (userAgent.indexOf('Firefox') > -1) { return 'Firefox'; } if (userAgent.indexOf('Safari') > -1 && userAgent.indexOf('Chrome') === -1) { return 'Safari'; } if (userAgent.indexOf('Chrome') > -1 && userAgent.indexOf('Safari') > -1) { return 'Chrome'; } if (!!window.ActiveXObject || 'ActiveXObject' in window) { return 'IE>=11'; } return 'Unkonwn'; } const curBrowser = getExploreName(); if (curBrowser !== 'Edge' && curBrowser !== 'Chrome') { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { //响应完成且成功 const div = document.createElement('div'); div.className = 'tipMessageBox'; div.innerText = xhr.responseText === 'zh_CN' ? '请切换至版本为70及以上的谷歌浏览器' : 'Switch to Google Chrome 70 or later.'; const loginPage = document.getElementById('loginPage'); document.body.insertBefore(div, loginPage); } } }; xhr.open('GET', '/rest/nmot/systemconfig/v1/getlocale', true); xhr.send(null); } </script> <link rel="shortcut icon" href="/nmotplatformwebsite/platform/favicon.ico"> <link href="/nmotplatformwebsite/platform/css/vendor.a54fa32d134cafcc5d6a.bundle.css?718eaa27bc2085fac411" rel="stylesheet"> <link href="/nmotplatformwebsite/platform/css/commons.491263d9bbc957b142f8.bundle.css?718eaa27bc2085fac411" rel="stylesheet"> <link href="/nmotplatformwebsite/platform/css/login.68000531be16d0217216.bundle.css?718eaa27bc2085fac411" rel="stylesheet"> </head> <body class="nmot_page ev_no_wcag"> <div id="loginPage" class="loginModulePage"></div> <script type="text/javascript" src="/nmotplatformwebsite/platform/js/vendor.a54fa32d134cafcc5d6a.nmotplatform.bundle.js?718eaa27bc2085fac411"> </script> <script type="text/javascript" src="/nmotplatformwebsite/platform/js/commons.491263d9bbc957b142f8.nmotplatform.bundle.js?718eaa27bc2085fac411"> </script> <script type="text/javascript" src="/nmotplatformwebsite/platform/js/login.68000531be16d0217216.js?718eaa27bc2085fac411"></script> </body> </html>
10-16
提供了一个基于51单片机的RFID门禁系统的完整资源文件,包括PCB图、原理图、论文以及源程序。该系统设计由单片机、RFID-RC522频射卡模块、LCD显示、灯控电路、蜂鸣器报警电路、存储模块和按键组成。系统支持通过密码和刷卡两种方式进行门禁控制,灯亮表示开门成功,蜂鸣器响表示开门失败。 资源内容 PCB图:包含系统的PCB设计图,方便用户进行硬件电路的制作和调试。 原理图:详细展示了系统的电路连接和模块布局,帮助用户理解系统的工作原理。 论文:提供了系统的详细设计思路、实现方法以及测试结果,适合学习和研究使用。 源程序:包含系统的全部源代码,用户可以根据需要进行修改和优化。 系统功能 刷卡开门:用户可以通过刷RFID卡进行门禁控制,系统会自动识别卡片并判断是否允许开门。 密码开门:用户可以通过输入预设密码进行门禁控制,系统会验证密码的正确性。 状态显示:系统通过LCD显示屏显示当前状态,如刷卡成功、密码错误等。 灯光提示:灯亮表示开门成功,灯灭表示开门失败或未操作。 蜂鸣器报警:当刷卡或密码输入错误时,蜂鸣器会发出报警声,提示用户操作失败。 适用人群 电子工程、自动化等相关专业的学生和研究人员。 对单片机和RFID技术感兴趣的爱好者。 需要开发类似门禁系统的工程师和开发者。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值