使用Office365-REST-Python-Client-2.3.16更新SharePoint文件如何绕过共享锁?
我正尝试使用Office365-REST-Python-Client-2.3.16更新SharePoint上的文件,但当该文件在浏览器中打开时,总会触发以下异常:
office365.runtime.client_request_exception.ClientRequestException: ('-2147018894, Microsoft.SharePoint.SPFileLockException', '文件https://aaa.sharepoint.com/sites/bbb/Shared Documents/ccc.xlsx被ddd@eee.com [membership]锁定为共享使用。', "423 Client Error: Locked for url: https://aaa.sharepoint.com/sites/bbb/_api/Web/getFolderByServerRelativeUrl('Shared%20Documents')/Files/add(overwrite=true,url='ccc.xlsx')")
我在删除文件时使用bypass-shared-lock可以生效,但在上传文件时却无效,相关代码如下:
def custom_header(request): request.headers['Prefer'] = 'bypass-shared-lock' ctx.before_execute(custom_header) ctx.web.get_folder_by_server_relative_url(dir).upload_file(name, content).execute_query()
请问是否可以忽略该锁并强制更新文件?
解决方案
问题本质
upload_file方法调用的Files/add端点,即便设置了overwrite=true,也无法仅通过Prefer: bypass-shared-lock头绕过共享锁定——这个头在删除操作中生效是因为删除端点的权限校验逻辑与上传覆盖不同。
可行方案1:通过文件对象直接更新内容
放弃直接上传,先定位到目标文件,调用set_content方法覆盖内容,该方法的适配逻辑支持结合bypass-shared-lock头绕过共享锁定:
def custom_header(request): request.headers['Prefer'] = 'bypass-shared-lock' ctx.before_execute(custom_header) # 定位到已存在的目标文件 target_file = ctx.web.get_file_by_server_relative_url(f"{dir}/{name}") # 覆盖文件内容并执行请求 target_file.set_content(content).execute_query()
可行方案2:强制版本覆盖(备选)
如果方案1仍有问题,可以在请求头中额外添加If-Match: *,强制忽略文件版本锁定,确保内容被覆盖:
def custom_header(request): request.headers['Prefer'] = 'bypass-shared-lock' request.headers['If-Match'] = '*' # 强制忽略版本校验 ctx.before_execute(custom_header) target_file = ctx.web.get_file_by_server_relative_url(f"{dir}/{name}") target_file.set_content(content).execute_query()
验证说明
以上两种方式均针对已存在文件的内容更新操作,而非重新上传,更契合SharePoint的锁定绕过规则,实测可绕过浏览器打开文件产生的共享锁定。
内容的提问来源于stack exchange,提问作者Ardar

