前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >WebViewJavascriptBridge

WebViewJavascriptBridge

作者头像
全栈程序员站长
发布于 2022-11-19 08:59:11
发布于 2022-11-19 08:59:11
1.4K02
代码可运行
举报
运行总次数:2
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

Web 页面中的 JS 与 iOS Native 如何交互?JS 和 iOS Native 就好比两块没有交集的大陆,如果想要使它们相互通信就必须要建立一座“桥梁”。

WebViewJavascriptBridge 是盛名已久的 JSBridge 库,它仅使用了少量代码就实现了对于 Mac OS X 的 WebView 以及 iOS 平台的 UIWebView 和 WKWebView 三种组件的完美支持。

WebViewJavascriptBridge 主要是作为 Mac OS X 和 iOS 端(Native 端)与 JS 端相互通信,互相调用的桥梁。对于 Mac OS X 和 iOS 两种平台包含的三种 WebView 功能组件而言,WebViewJavascriptBridge 做了隐性适配,即仅用一套代码即可绑定不同平台的 WebView 组件实现同样功能的 JS 通信功能。 WebViewJavascriptBridge 对于 JS 端和 Native 端设计了对等的接口,不论是 JS 端还是 Native 端,注册本端的响应处理都是用 registerHandler 接口,调用另一端(给另一端发消息)都是用 callHandler 接口。

  1. UIWebView 使用 javaScriptCore.
  2. WKWebView 使用 WKUserContentController.

UIWebView 原生的交互原理 通过一个 JSContext 获取 UIWebView 的 JS 执行上下文。 然后通过这个上下文,进行 OC & JS 的双端交互。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 _jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    _jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
        NSLog(@"%@",@"获取 WebView JS 执行环境失败了!");
    };

WKWebView 原生交互原理

通过 userContentController 把需要观察的 JS 执行函数注册起来。 然后通过一个协议方法,将所有注册过的 JS 函数执行的参数传递到此协议方法中。

注册 需要 观察的 JS 执行函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 [webView.configuration.userContentController addScriptMessageHandler:self name:@"jsFunc"];

在 JS 中调用这个函数并传递参数数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
window.webkit.messageHandlers.jsFunc.postMessage({name : "李四",age : 22});

OC 中遵守 WKScriptMessageHandler 协议。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message 

此协议方法里的 WKScriptMessage 有 name & body 两个属性。 name 可以用来判断是哪个 JSFunc 调用了。body 则是 JSFunc 传递到 OC 的参数。

WebViewJavaScriptBridge

WebViewJavaScriptBridge 用于 WKWebView & UIWebView 中 OC 和 JS 交互。 它的基本原理是:

把 OC 的方法注册到桥梁中,让 JS 去调用。 把 JS 的方法注册在桥梁中,让 OC 去调用。

WebViewJavaScriptBridge 使用的基本步骤

  1. 首先在项目中导入 WebViewJavaScriptBridge 框架
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pod ‘WebViewJavascriptBridge’
  1. 导入头文件 #import <WebViewJavascriptBridge.h>
  2. 建立 WebViewJavaScriptBridge 和 WebView 之间的关系。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
_jsBridge = [WebViewJavascriptBridge bridgeForWebView:_webView];
  1. 在HTML 文件中,复制粘贴这两段 JS 函数。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function setupWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
          return callback(window.WebViewJavascriptBridge)
        }
        if (window.WVJBCallbacks) {
          return window.WVJBCallbacks.push(callback)
        }
        window.WVJBCallbacks = [callback] // 创建一个 WVJBCallbacks 全局属性数组,并将 callback 插入到数组中。
        var WVJBIframe = document.createElement('iframe') // 创建一个 iframe 元素
        WVJBIframe.style.display = 'none' // 不显示
        WVJBIframe.src = 'https://__bridge_loaded__' // 设置 iframe 的 src 属性
        document.documentElement.appendChild(WVJBIframe) // 把 iframe 添加到当前文导航上。
        setTimeout(function() {
          document.documentElement.removeChild(WVJBIframe)
        }, 0)
    }
    
    // 这里主要是注册 OC 将要调用的 JS 方法。
    setupWebViewJavascriptBridge(function(bridge){
       
    });

到此为止,基本的准备工作就做完了。现在需要往桥梁中注入 OC 方法 和 JS 函数了。

往桥梁中注入 OC 方法 和 JS 函数

1、往桥梁中注入 OC 方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 [_jsBridge registerHandler:@"scanClick" handler:^(id data, WVJBResponseCallback responseCallback) {
        NSLog(@"dataFrom JS : %@",data[@"data"]);
        
        responseCallback(@"扫描结果 : www.baidu.com");
    }];

这段代码的意思:

  1. scanClick 是 OC block 的一个别名。
  2. block 本身,是 JS 通过某种方式调用到 scanClick 的时候,执行的代码块。
  3. data ,由于 OC 这端由 JS 调用,所以 data 是 JS 端传递过来的数据。
  4. responseCallback OC 端的 block 执行完毕之后,往 JS 端传递的数据。

2、往桥梁中注入 JS 函数. 在 JS 的方法如何注入到桥梁呢?需要在第二段 JS 代码中,注入 JS 的函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 这里主要是注册 OC 将要调用的 JS 方法。
    setupWebViewJavascriptBridge(function(bridge){
        // 声明 OC 需要调用的 JS 方法。
        bridge.registerHanlder('testJavaScriptFunction',function(data,responseCallback){
            // data 是 OC 传递过来的数据.
            // responseCallback 是 JS 调用完毕之后传递给 OC 的数据
            alert("JS 被 OC 调用了.");
            responseCallback({data: "js 的数据",from : "JS"});
        })
    });

这段代码的意思:

  1. testJavaScriptFunction 是注入到桥梁中 JS 函数的别名。以供 OC 端调用。
  2. 回调函数的 data。 既然 JS 函数由 OC 调用,所以 data 是 OC 端传递过来的数据。
  3. responseCallback 。 JS 调用在被 OC 调用完毕之后,向 OC 端传递的数据。

基本就是:

OC 端注册 OC 的方法,OC 端调用 JS 的函数。 JS 端注册 JS 的函数,JS 端调用 OC 的方法。

场景

JS -> OC 的交互

在 HTML 中,有个按钮,点击这个按钮,修改 NavigationBar 的颜色。

  1. 在 OC 端,往桥梁注入一个修改 NavigationBar 颜色的 block.
  2. 在 JS 端,调用这个 block,来间接的达到修改颜色的目的。

首先,在 OC 中,通过 WebViewJavascriptBridge 注册一个修改 navigationBar 颜色的 Block。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[_jsBridge registerHandler:@"colorClick" handler:^(id data, WVJBResponseCallback responseCallback) {
       self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:arc4random_uniform(256) / 255.0 green:arc4random_uniform(256) / 255.0 blue:arc4random_uniform(256) / 255.0 alpha:1.0];
        
        responseCallback(@"颜色修改完毕!");
    }];

然后再 JS 中,通过某种方式去调用这个 OC 的 block。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
WebViewJavascriptBridge.callHandler('colorClick',function(dataFromOC) {
            alert("JS 调用了 OC 注册的 colorClick 方法");
            document.getElementById("returnValue").value = dataFromOC;
        })

这里通过某种方式就是使用 WebViewJavascriptBridge.callHandler(‘OC 中block 别名’,callback)的方式来调用。

OC -> JS 的交互

OC 上有一个UIButton,点击这儿按钮,把 HTML body 的颜色修改成橙色。

首先,往桥梁中,注入一个修改 HTML body 颜色的 JSFunction。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 在这里声明 OC 需要主动调用 JS 的方法。
    setupWebViewJavascriptBridge(function(bridge) {
        bridge.registerHandler('changeBGColor',function(data,responseCallback){
            // alert('aaaaaa');
            document.body.style.backgroundColor = "orange";
            document.getElementById("returnValue").value = data;
        });
    }); 

然后在 OC 端通过桥梁调用这个 changeBGColor

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 [_jsBridge callHandler:@"changeBGColor" data:@"把 HTML 的背景颜色改成橙色!!!!"];

执行效果:


补充

OC 调用 JS 的三种情况。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // 单纯的调用 JSFunction,不往 JS 传递参数,也不需要 JSFunction 的返回值。
    [_jsBridge callHandler:@"changeBGColor"];
    // 调用 JSFunction,并向 JS 传递参数,但不需要 JSFunciton 的返回值。
    [_jsBridge callHandler:@"changeBGColor" data:@"把 HTML 的背景颜色改成橙色!!!!"];
    // 调用 JSFunction ,并向 JS 传递参数,也需要 JSFunction 的返回值。
    [_jsBridge callHandler:@"changeBGColor" data:@"传递给 JS 的参数" responseCallback:^(id responseData) {
        NSLog(@"JS 的返回值: %@",responseData);
    }];

JS 调用 OC 的三种情况。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// JS 单纯的调用 OC 的 block
WebViewJavascriptBridge.callHandler('scanClick');

// JS 调用 OC 的 block,并传递 JS 参数
WebViewJavascriptBridge.callHandler('scanClick',"JS 参数");

// JS 调用 OC 的 block,传递 JS 参数,并接受 OC 的返回值。
WebViewJavascriptBridge.callHandler('scanClick',{data : "这是 JS 传递到 OC 的扫描数据"},function(dataFromOC){
            alert("JS 调用了 OC 的扫描方法!");
            document.getElementById("returnValue").value = dataFromOC;
        });

可以根据实际情况,选择合适的方法。

关于在 OC 中,往桥梁中注入 block 的注意点。

在当前控制器消失的时候,要记得把注入到桥梁中的 OC block,从桥梁中删除。 否则,可能会出现控制器无法释放的情况。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [_jsBridge removeHandler:@"scanClick"];
    [_jsBridge removeHandler:@"colorClick"];
    [_jsBridge removeHandler:@"locationClick"];
    [_jsBridge removeHandler:@"shareClick"];
    [_jsBridge removeHandler:@"payClick"];
    [_jsBridge removeHandler:@"goBackClick"];
}

Android

以上说的都是ios交互,安卓有一点点不同。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function connectWebViewJavascriptBridge (callback) { 
     if (window.WebViewJavascriptBridge) {
           callback(WebViewJavascriptBridge)
     } else {
           document.addEventListener(
               'WebViewJavascriptBridgeReady'
                , function() {
                     callback(WebViewJavascriptBridge)
                },
                false
           );
     }
}


//和ios一样
connectWebViewJavascriptBridge (function(bridge) {

    //注册一个方法(方法名是“JS Echo”),客户端进行调用(方法名也是“JS Echo”),responseCallback是回调函数
    bridge.registerHandler('JS Echo', function(data, responseCallback) {
        console.log("JS Echo called with:", data)
        responseCallback(data)
    })

    //客户端已经注册好一个名为“ObjC Echo”的方法,H5直接进行调用(方法名也为“ObjC Echo”)就行,调用的时候可以传客户端需要的参数
    bridge.callHandler('ObjC Echo', {'key':'value'}, function responseCallback(responseData) {
        console.log("JS received response:", responseData)
    })
})

封装:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* eslint-disable */
function setAndroid () {
var bridge = {
default: this,
callHandler: function(b, a, c) {
var e = ''
'function' == typeof a && ((c = a), (a = {}))
a = { data: void 0 === a ? null : a }
if ('function' == typeof c) {
var g = 'dscb' + window.dscb++
window[g] = c
a._dscbstub = g
}
a = JSON.stringify(a)
if (window._dsbridge) e = _dsbridge.callHandler(b, a)
else if (
window._dswk ||
-1 != navigator.userAgent.indexOf('_dsbridge')
)
e = prompt('_dsbridge=' + b, a)
return JSON.parse(e || '{}').data
},
register: function(b, a, c) {
c = c ? window._dsaf : window._dsf
window._dsInit ||
((window._dsInit = !0),
setTimeout(function() {
bridge.callHandler('_dsb.dsinit')
}, 0))
'object' == typeof a ? (c._obs[b] = a) : (c[b] = a)
},
registerAsyn: function(b, a) {
this.register(b, a, !0)
},
hasNativeMethod: function(b, a) {
return this.callHandler('_dsb.hasNativeMethod', {
name: b,
type: a || 'all'
})
},
disableJavascriptDialogBlock: function(b) {
this.call('_dsb.disableJavascriptDialogBlock', {
disable: !1 !== b
})
}
}
!(function() {
if (!window._dsf) {
var b = {
_dsf: { _obs: {} },
_dsaf: { _obs: {} },
dscb: 0,
WebViewJavascriptBridge: bridge,
close: function() {
bridge.callHandler('_dsb.closePage')
},
_handleMessageFromNative: function(a) {
var e = JSON.parse(a.data),
b = { id: a.callbackId, complete: !0 },
c = this._dsf[a.method],
d = this._dsaf[a.method],
h = function(a, c) {
b.data = a.apply(c, e)
bridge.call('_dsb.returnValue', b)
},
k = function(a, c) {
e.push(function(a, c) {
b.data = a
b.complete = !1 !== c
bridge.callHandler('_dsb.returnValue', b)
})
a.apply(c, e)
}
if (c) h(c, this._dsf)
else if (d) k(d, this._dsaf)
else if (((c = a.method.split('.')), !(2 > c.length))) {
a = c.pop()
var c = c.join('.'),
d = this._dsf._obs,
d = d[c] || {},
f = d[a]
f && 'function' == typeof f
? h(f, d)
: ((d = this._dsaf._obs),
(d = d[c] || {}),
(f = d[a]) &&
'function' == typeof f &&
k(f, d))
}
}
},
a
for (a in b) window[a] = b[a]
bridge.register('_hasJavascriptMethod', function(a, b) {
b = a.split('.')
if (2 > b.length) return !(!_dsf[b] && !_dsaf[b])
a = b.pop()
b = b.join('.')
return (b = _dsf._obs[b] || _dsaf._obs[b]) && !!b[a]
})
}
})();
return bridge
}
const jsBridge = {
init: function() {
if (/(Android)/i.test(navigator.userAgent.toLowerCase())) {
// setAndroid()
this.register = setAndroid().register
}
},
connectJsBridge: function(callback) {
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge)
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback)
}
window.WVJBCallbacks = [callback]
var WVJBIframe = document.createElement('iframe')
WVJBIframe.style.display = 'none'
WVJBIframe.src = 'https://__bridge_loaded__'
document.documentElement.appendChild(WVJBIframe)
setTimeout(function() {
document.documentElement.removeChild(WVJBIframe)
}, 0)
},
addBridgeProperty: function(bridge) {
const dependencies = ['getUserInfo', 'login', 'getLocation', 'share',..... ];
try {
dependencies.forEach(dependency => {
// if (!this[dependency]) {
Object.defineProperty(this, dependency, {
configurable: true,  // 注:允许重复定义属性(移除会造成重新定义报错)
get: () => {
return bridge.callHandler.bind(bridge, dependency)
}
})
// }
})
} catch (error) {
console.error(error)
}
// if (this.openWebPage) {
this.openWebPage = url => {
window.location.href = `app内嵌的域名?url=${encodeURIComponent(
url
)}`
}
// }
return this
},
ready: function(callback) {
this.connectJsBridge(bridge => {
callback(this.addBridgeProperty(bridge))
})
},
register: function(...args) {
window.WebViewJavascriptBridge.registerHandler(...args)
},
}
jsBridge.init()
export default jsBridge
//使用:
import JSBridge from './base/jsBridge'
JSBridge.ready((bridge: any) => {
bridge.getUserInfo((json: string | object) => {
console.log(json)
})
})

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/198352.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月21日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
使用SQL Server维护计划实现数据库定时自动备份
在SQL Server中出于数据安全的考虑,所以需要定期的备份数据库。而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行,所以我们不可能要求管理员每天守到晚上1点去备份数据库。要实现数据库的定时自动备份,最常用的方式就是使用SQL Server代理中的作业。启动SQL Server Agent服务,然后在其中新建作业,作业中添加1个备份步骤,类型是T-SQL脚本,然后在命令中输入如下SQL语句,该语句实现了对数据库TestDB1的完整备份,备份文件在C盘Backup文件夹中,文件名就是TestDB1+当时备份的日期字符串.bak。
深蓝studyzy
2022/06/16
3K0
使用SQL Server维护计划实现数据库定时自动备份
SQL Server 代理进阶 - Level 2 :作业步骤和子系统
作者:Richard Waymire,2017/10/11(第一版:2011/02/17) 关于系列 本文属于Stairway系列:Stairway to SQL Server Agent SQL Server Agent是任何实时数据库系统的核心。 代理有许多用途并不总是显而易见的,因此对于开发人员和DBA来说,系统知识总是有用的。 理查德Waymire提供了一个简单的解释,它的许多用途。 SQL Server代理作业由一系列一个或多个作业步骤组成。作业步骤被分配给特定的作业子系统,该作业子系统标识作业步
Woodson
2018/07/19
1.4K0
SQL Server基础:数据表完整性约束、索引、视图的操作
  本文介绍基于Microsoft SQL Server软件,实现数据库表完整性约束、索引与视图的创建、编辑与删除等操作的方法。
疯狂学习GIS
2025/03/20
5880
SQL Server基础:数据表完整性约束、索引、视图的操作
SQL之收集SQL Server线程等待信息
要知道线程等待时间是制约SQL Server效率的重要原因,这一个随笔中将学习怎样收集SQL Server中的线程等待时间,类型等信息,这些信息是进行数据库优化的依据。 sys.dm_os_wait_stats 这是一个系统视图,里面存储线程所遇到的所有的等待信息,具体的列如下表 列名 数据类型 说明 Wait_type Nvarchar(60) 等待类型名称 waiting_tasks_count Bigint 等待类型的等待数。该计数器在每
欢醉
2018/01/22
1.2K0
SQL之收集SQL Server线程等待信息
SQL Server 2008新特性——SSMS增强
SQL Server 2008已经发布很多天了,今天来总结一下我们最常用的工具SSMS在SQL 2008中的一些改进:
深蓝studyzy
2022/06/16
1.7K0
SQL Server 2008新特性——SSMS增强
windows服务器如何设置对指定IP地址进行远程访问?
  因为存在:Windows server 2003、2008、2012及Linux这几种主流服务器。
习惯说一说
2019/06/30
17K0
windows服务器如何设置对指定IP地址进行远程访问?
关闭Windows自动更新的6种方法
这里我们将为您分享6种关闭Win10自动更新的方法,分别是通过Windows设置、Windows Update服务、本地组策略编辑器、任务计划程序、注册表编辑器来关闭Win10自动更新。
人不走空
2024/02/21
2K0
关闭Windows自动更新的6种方法
经典SQL语句大全之基本函数
1,datalength(Char_expr) 返回字符串包含字符数,但不包含后面的空格 2,substring(expression,start,length) 取子串,字符串的下标是从“1”,start为起始位置,length为字符串长度,实际应用中以len(expression)取得其长度 3,right(char_expr,int_expr) 返回字符串右边第int_expr个字符,还用left于之相反 4,isnull( check_expression , replacement_value )如果check_expression為空,則返回replacement_value的值,不為空,就返回check_expression字符操作类
陈珙
2018/09/12
7730
怎么关闭win10自动更新?有哪些好的方法?
win10从发布到现在也已经有好几年的时间了,相信很多人也都在用win10,从功能方面来讲的话,这个系统的功能还是挺好用的,但是也有不少人吐槽这个系统的自动更新功能,因为这个自动更新功能可是让不少人吃了苦头。毕竟win10的自动更新功能是不可预期,不可控制的,毫无征兆地就自动更新了,所以带来的烦恼和问题也会比较多。那么怎么关闭win10自动更新?有哪些好的方法?
用户8715145
2021/07/09
1.2K0
在 BizTalk Server 2004 SP2 中存档和清除 BizTalk 跟踪数据库
在 Biztalk Server 2004 SP2 中存档和清除 Biztalk 跟踪数据库 发布日期: 2006年09月19日 小结:本白皮书介绍如何配置 Biztalk Server 2004 SP2,以利用自动存档和清除 Biztalk 跟踪数据库的功能。它还介绍了为实现和维持高性能在配置过程中需要考虑的因素。 本页内 自动存档和清除功能的工作原理 如何配置 BTS_BACKUP_USERS 角色以存档和清除 BizTalk 跟踪数据库中的数据 如何配置 DTA 清除和存档作业
阿新
2018/04/12
2.2K0
Windows 操作系统的安全设置
  在选用操作系统时,最好不要选择Ghost版的Windows XP系统,因为使用此系统版本的用户,默认情况下会自动开启远程终端服务,并且还会存在一个弱口令形式的new账号,两者很容易被黑客利用,从而导致最后计算机被别有用心的人入侵。当然如果只有Ghost版的Windows XP系统安装盘也没关系,不过要注意的是请在系统安装完成后,依次单击“开始” →“运行”选项,在打开的“运行”对话框内,输入services.msc命令回车,此时就会启动“服务”列表对话框。从中找到terminal services服务项后,将其属性更改为“已禁用”选项确定即可。
会长君
2023/04/26
1.3K0
【SQL Server】在 SSMS 中 使用 生成 SQL 脚本 方式 实现 数据库 备份 / 还原 ( 数据备份操作 - 生成 SQL 脚本 | 数据还原操作 - 执行 SQL 脚本 )
SSMS 全称 " SQL Server Management Studio " , 是 由 Microsoft 开发的一款集成式环境 , 用于管理 Microsoft SQL Server 的数据库 ;
韩曙亮
2024/08/09
1.6K0
【SQL Server】在 SSMS 中 使用 生成 SQL 脚本 方式 实现 数据库 备份 / 还原 ( 数据备份操作 - 生成 SQL 脚本 | 数据还原操作 - 执行 SQL 脚本 )
如何使用SQL Server配置管理器
SQL Server configuration manager is a tool provided by Microsoft SQL Server. When we install SQL Server, it is installed automatically. It is used for the following purposes.
全栈程序员站长
2022/09/13
3K0
如何使用SQL Server配置管理器
我们一起学一学渗透测试——黑客应该掌握的Windows基础
今天我们看看作为一个黑客对于Windows应该掌握哪些基础知识,主要内容包含以下四个方面:
菜鸟小白的学习分享
2020/08/04
2.8K0
我们一起学一学渗透测试——黑客应该掌握的Windows基础
Mysql Workbench使用教程
MySQL Workbench 为数据库管理员、程序开发者和系统规划师提供可视化的Sql开发、数据库建模、以及数据库管理功能。
全栈程序员站长
2022/09/05
8.8K0
Mysql Workbench使用教程
windows7如何关闭445端口_win10重装win7的后果
勒索病毒最新变种2.0已导致我国的很多行业遭受袭击。勒索病毒是通过入侵端口传播,主要是445端口,用户可以通过关闭445端口可以有效预防勒索病毒。下面重点介绍如何关闭445端口。
全栈程序员站长
2022/11/03
3K0
windows7如何关闭445端口_win10重装win7的后果
Win Server 2003 10条小技巧
微软推出Windows Server 2003已经有一段时间了,但是,由于它是一个面向企业用户的服务器操作系统,所以,没有引起更多个人用户的注意。实际上,简单地改变一下系统的设置,您也可以将Windows Server 2003当成个人电脑的操作系统来使用。而且,大部分曾经测试过Windows Server 2003的用户都反映,这一操作系统给用户的感觉要比Windows XP稳定,比Windows 2000速度更快。      Windows Server 2003操作系统的默认设置大部分都是按服务器的需要进行配置的,它只提供服务器上的组件和管理工具。为此,笔者就相关的问题查阅了国外一些参加Windows Server 2003操作系统评测的专家撰写的资料,在对正式版的Windows Server 2003进行研究和测试后,总结出以下十条经验技巧,可以使您的Windows Server 2003系统无论从界面还是功能、性能上都比较接近个人电脑操作系统。      但需要提醒您的是,由于Windows Server 2003推广的时间较短,而且属于服务器操作系统,一些硬件由于缺少驱动程序可能无法正常使用。另外,最大的问题是一些在安装时需要区分服务器版本和个人用户版本的应用软件,在安装时将很难按照用户的意愿进行。这些问题都暂时还没有比较理想的办法可以解决。Windows Server 2003可以和Windows 98、Windows XP安装在同一台电脑上。  Windows Server 2003 自动登录     每次启动Windows Server 2003,系统会要求您在键盘上按下“Ctrl+Alt+Del”键(如图1),然后输入用户名与密码才能登录系统。对于服务器来说,这样有助于提高系统的安全性;但对个人用户来说,这样就有些麻烦了。所以,我们要做的第一件事情就是将系统改为自动登录,要做到这一点我们有两种方法可选。 
流柯
2018/08/30
2.6K0
Navicat for MySQL定时备份数据库及数据恢复
在做数据库修改或删除操作中,可能会导致数据错误,甚至数据库奔溃,而有效的定时备份能很好地保护数据库。本篇文章主要讲述Navicat for MySQL定时备份数据库和数据恢复等功能,同时可以定时播放电影等设置,希望对您有所帮助,如果文章中存在错误或不足之处,还请海涵~
星哥玩云
2022/08/13
1.7K0
Navicat for MySQL定时备份数据库及数据恢复
SQL Server安全(2/11):身份验证(Authentication)
在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切。但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念。这篇文章提供了基础,因此你可以对SQL Server里的安全功能充分利用,不用在面对特定威胁,不能保护你数据的功能上浪费时间。 身份验证是验证主体(需要访问SQL Server数据库的用户或进程,是声称是的人或物)的过程。主体需要唯一的身份,这样的话SQL Server可以决定主体有哪个许可。在提供安全访问数据库对象中,正确的身份验证是必须的第一步。 S
逸鹏
2018/04/10
2.6K0
SQL Server安全(2/11):身份验证(Authentication)
SQL Server 2008数据库定期自动备份的设置
SQL Server2008 本身具有定期自动备份功能,我们只需要通过简单的配置就可以实现非常简单高效的自动备份功能。
星哥玩云
2022/08/17
3.1K0
SQL Server 2008数据库定期自动备份的设置
推荐阅读
相关推荐
使用SQL Server维护计划实现数据库定时自动备份
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档